Twemproxy(Nutcracker)源码分析-系统中的in_q和out_q TAILQ队列

nc是对客户端的请求进行转发,转发给后端server,并保证后端的请求有序的返回给请求客户端。由于nc基本上连接的客户端连接应该远远大于nc连接的后端,所以具体某个客户端的多个请求会转发给多个不同的后端,所以同一个客户端的请求到达后端后数据返回的顺序会不一致,这个需要解决;nc转发给后端的都是异步请求,所以需要保证每个后端的请求都要有对应的response。

nc实现的机制是使用了inq和outq队列完成的。Client和Server类型对应的connection都有一个inq和outq队列。

client conn中的out_q队列保证了客户端得到的回复和客户端的请求顺序一致性。

server conn中的in_q队列保证了nc对后端的每一个请求都会有一个response。

一个请求从客户端发送给nc,然后nc转发给后端,后端返回后将请求的数据返回给nc,nc会将数据在转发给客户端。这个过程中请求的流转过程如下,

客户端请求->nc:

msg_recv()->msg_recv_chain()->msg_parse()->msg_parsed()->req_recv_done()

上面是一个请求到来时函数的调用过程,在req_recv_done()函数中会调用req_filter()和req_forward()函数。

req_filter()函数是对无效的命令进行过滤。

req_forward()函数是(1)将msg请求放入client conn的out_q队列;(2)将msg放入server conn的in_q队列。

nc->服务后端:

msg_send()->msg_send_chain()

在msg_send_chain()函数中会先后调用conn_sendv()函数和req_send_done()函数。

conn_sendv()函数是会将msg发送给后端server。

req_send_done()函数会将请求msg从server conn的in_q队列中出队,并将该msg加入server conn的out_q队列中。

服务后端->nc:

msg_recv()->msg_recv_chain()->msg_parse()->msg_parsed()->rsp_recv_done()

函数rsp_recv_done()函数会先后调用rsp_filter()和rsp_forward()函数。

rsp_filter()是对请求进行过滤。

rsp_forward()是将请求msg从server的out_q队列出队,并绑定请求msg和响应msg。

nc->客户端:

msg_send()->msg_send_chain()->rsp_send_done()

rsp_send_done()函数中将请求的msg从client的out_q出队,表明了客户端按正确的顺序接收到了响应。

About 智足者富

http://chenpeng.info

发表评论

电子邮件地址不会被公开。 必填项已用*标注

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>