twemproxy0.4原理分析-消息处理过程详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zg_hover/article/details/85843142

概述

本文讲述了twemproxy0.4的消息处理流程。通过本文可以了解到twemproxy0.4的消息处理全流程。

流程总体描述

作为一个代理服务器twemproxy0.4,首先要接收来自client的了解,和client端建立好连接;然后,需要后后端的服务器建立连接,并把从client端接收到的连接发送给后端服务器,然后把服务器端的返回信息通过和client的连接发送给client。最后完成整个流程。

本章我们来具体分析一下twemproxy0.4是如何处理这些消息的。

处理客户端的连接请求

如上图所示,客户端向配置好的twemproxy的监听地址发送连接请求,twemproxy接收连接请求,完成tcp三次握手后(调用accept函数)会创建一个新的已连接文件描述符newfd,twemproxy把该newfd添加到事件处理框架中,若客户端有消息到来,就会产生读事件,进入消息处理流程。

消息处理初始化

启动时的初始化

twemproxy0.4启动时的初始化代码相对简单,启动代码在文件src/nc.c中,main作为软件入口,其函数调用关系如下:

main()
   -> nc_pre_run(&nci)
   -> nc_run(&nci) 
      -> core_start(nci) //这里进行软件的初始化
      -> core_loop(ctx)  // 这里进入事件处理循环
      -> core_stop(ctx)  //若软件停止运行,执行这里
   -> nc_post_run(&nci) //软件退出,需要做一些清理工作

而在core_start会完成整个软件的初始化,在该函数中的函数调用关系如下:

core_start(struct instance *nci)
   ->mbuf_init(nci); // mbuf管理机制初始化
   ->msg_init(); // msg处理机制初始化
   ->conn_init(); // conn结构管理初始化
   ->core_ctx_create(nci); //进入核心事件处理循环
   ->conn_deinit();
   ->msg_deinit();
   ->mbuf_deinit();

消息处理初始化,从上面的调用关系我们可以看到,消息处理机制的初始化在函数core_ctx_create中完成,该函数的函数调用关系如下:

core_ctx_create(struct instance *nci)
   -> conf_create()
   -> server_pool_init()
   -> core_calc_connections()
   -> stats_create()
   -> event_base_create()   // 设置事件处理函数
   -> server_pool_preconnect()  // 预先和后台的redis或memcached server建立连接
   -> proxy_init() // 创建连接监听socket,监听来自客户端的连接请求

最终完成和client端的连接后,会把recv函数设置成:msg_recv。正式进入client的消息处理循环。

消息处理流程概览

说明:
(1) 正常的完整的消息处理流程是:

过程a->过程b->过程c->过程d

(2) 处理客户端(client)端请求的流程是:

过程a->过程b

(3) 处理后端服务器返回数据的流程是:

过程c->过程d

消息处理流程详解

消息从客户端到后端redis/memcached服务器需要经历以下几步:

  • (1) 接收client端的消息
  • (2) 把client端的消息转发给后端redis/memcached服务器
  • (3) 接收后端redis/memcached服务器的返回消息
  • (4) 把后端redis/memcached服务器的返回消息转发送给client端

下面分别介绍这几步的实现原理:

twemproxy和client 及其 server端的连接示意

假设twemproxy和client端建立的连接名称为:client_conn,和后端的redis/memcached建立的连接是:server_conn。

接收client端的消息

twemproxy接收客户端的请求流程如下:

twemproxy接收客户端的请求是基于client_conn连接进行的,基于该连接在事件处理框架中注册的读事件(read event)来监听和触发客户端的发送的消息。

注意:该流程中有一个环节是处理fragment消息,对于fragment的处理会在后面的文章中进行分析。

转发client端的消息给后端redis/memcached服务器

twemproxy从client接受完消息后,会放到和客户端连接的输出队里中,在转发client端消息时,只需要从该队列中获取消息即可。处理过程如下:

完成转发消息是通过在server_conn连接的fd上注册写事件来触发的。

接收后端redis/memcached服务器的返回消息

通过上面的两个流程已经把客户端的消息发送给后端redis/memached服务器了,该流程从redis/memached服务器读取返回消息,具体流程如下图所示:

基于server_conn注册读事件,触发读取redis/memcached服务器的返回消息。

转发从后端redis/memcached服务器接收到的消息给client端

把redis/memcached的返回消息返回给client端是通过在client_conn的fd上注册写事件来完成的。具体流程如下图所示:

总结

本文分析了twemproxy的消息处理流程,可以看出twemproxy通过事件处理框架和两个消息队列来完成整个消息传递过程。

猜你喜欢

转载自blog.csdn.net/zg_hover/article/details/85843142