zoukankan      html  css  js  c++  java
  • twemproxy代理主干流程——剖析twemproxy代码正编

    在twemproxy的发送和接收流程剖析中,我们已经完全弄清楚twemproxy如何将客户端以及服务端发来的包切分成msg,获得一个独立的msg后twemproxy应该如何处理?这是本文这次需要重点介绍的内容。

    twemproxy的主干流程

    图1 twemproxy的主干流程

    如图1所示,twemproxy主要通过3个队列进行模块间的数据交互:客户端连接conn的发送队列conn->omsg_q,服务端连接s_conn的输入队列s_conn->imsg_q,服务端连接s_conn的发送队列s_conn->omsg_q以及conn->omsg_q里的msg的对应回复peer。

    • 客户层接收模块将所有需要回复的msg处理后分别写入到客户端conn连接的发送队列conn->omsg_q以及服务端连接s_conn的输入队列s_conn->imsg_q。
    • 服务层发送模块从服务端连接s_conn的输入队列s_conn->imsg_q取出,将其发送后写入服务端连接s_conn的发送队列s_conn->omsg_q。
    • 服务层接收模块将接到服务端的响应通过s_conn->omsg_q的提供顺序将回复的msg写入到conn->omsg_q里的msg的对应回复peer。
    • 客户层发送模块通过客户端连接conn的发送队列conn->omsg_q的顺序获得请求msg的对应的peer中的回复msg,然后发送个客户端。

    由于twemproxy的队列里的元素是msg对象的指针,同样peer也是msg对象的指针,为此在twemproxy在接到请求直至发送回复的那段时间里没有进行内存拷贝,仅有在接收的时候申请内存。twemproxy通过这种精巧的设计使得内存零拷贝,同时配合空闲msg池的使用,大幅减少了系统申请和释放内存的次数,大幅提高了twemproxy性能,大幅减轻了twemproxycpu的压力。

    twemproxy的客户层接收模块

     

    图2 twemproxy的客户层接收

    如图2,当客户层接收模块接收到客户端请求后:

    • twemproxy会从空闲msg池和系统内存中请求空的msg,通过我们提到过的接收流程接收并解析客户端请求生成msg。
    • 解析后发现如果类型是mset,mget或者del的多key操作,根据key值进行分片操作将一个msg分成多个msg。
    • 将这些msg按顺序放入客户端连接conn的发送队列conn->omsg_q中(其中被分片的msg不放入服务端连接s_conn的输入队列s_conn->imsg_q中)。
    • 根据key值经过哈希建立对应的服务端连接,每个服务端在twemproxy中对应一个key值。
    • 在建立连接后,将msg插入服务端连接s_conn的输入队列s_conn->imsg_q中,并通知服务端层发送模块发送。

     twemproxy的服务层发送模块

     

    图3 twemproxy的服务层发送 

    如图3所示,当服务层接收模块接收到客户层接收模块的通知后:

    • twemproxy从服务端连接s_conn的输入队列s_conn->imsg_q中取出msg。
    • 在相应的s_conn发送msg,从服务端连接s_conn的输入队列s_conn->imsg_q中删除。
    • 发送后,将发送过的msg插入到服务端连接s_conn的发送队列s_conn->omsg_q中。

     twemproxy的服务层接收模块

     

    图4 twemproxy的服务层接收

    如图4所示,当服务层接收模块接收到服务端回复后:

    • twemproxy会从空闲msg池和系统内存中请求空的msg,通过我们提到过的接收流程接收并解析服务端回复生成msg。
    • 从服务端连接s_conn的发送队列s_conn->omsg_q中取出对应的客户端请求pmsg。
    • 查看客户端请求pmsg和客户端msg是否对应,msg可能需要被丢弃(因为在此时客户端连接断开,msg不能被发送),并将丢弃的msg放入空闲msg池中。
    • 将msg写入pmsg->peer中,然后从服务端连接s_conn的发送队列s_conn->omsg_q中删除pmsg。
    • 如果存在分片,那么在所有已经分片的msg收到请求回复后,将这些已经分片的msg并入被分片的msg中。
    • 将所有已经分片的msg置空,并将该消息通知给服务层接收模块。

    twemproxy的客户层发送模块

     

    图5 twemproxy的客户层发送

    如图5所示,当客户层接收模块接收到服务层接收模块的通知后:

    • twemproxy从客户端连接conn的发送队列conn->omsg_q取出msg。
    • 将msg->peek中取出对应的回复pmsg并发送。
    • 从客户端连接conn的发送队列conn->omsg_q删除msg。
    • 将msg释放后放入空闲msg池。

    总结

    twemproxy通过客户端连接conn的发送队列conn->omsg_q,服务端连接s_conn的输入队列s_conn->imsg_q,服务端连接s_conn的发送队列s_conn->omsg_q以及conn->omsg_q里的msg的对应回复peer来完成twemproxy的代理服务,利用队列和peer指针特性实现了内存零拷贝。

  • 相关阅读:
    虚函数和纯虚函数
    MS CRM 2011中PartyList类型字段的实例化
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(4)
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(2)
    MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第二部分)——IOrganizationService(二)
    MS CRM 2011 SDK 5.08已经发布
    MS CRM 2011 Q2的一些更新
    最近很忙
    Microsoft Dynamics CRM 2011最近的一些更新
    补一篇,Update Rollup 12 终于发布了
  • 原文地址:https://www.cnblogs.com/onlyac/p/7079441.html
Copyright © 2011-2022 走看看