1. 程式人生 > >twemproxy原始碼分析之四:處理流程

twemproxy原始碼分析之四:處理流程

很讚的註釋:

*                   nc_connection.[ch]
*                Connection (struct conn)
*                 +         +          +
*                 |         |          |
*                 |       Proxy        |
*                 |     nc_proxy.[ch]  |
*                 /                    \
*              Client                Server
*           nc_client.[ch]         nc_server.[ch]
*            nc_message.[ch]
*        _message (struct msg)
*            +        +            .
*            |        |            .
*            /        \            .
*         Request    Response      .../ nc_mbuf.[ch]  (mesage buffers)
*      nc_request.c  nc_response.c .../ nc_memcache.c; nc_redis.c (_message parser)

* Messages in nutcracker are manipulated by a chain of processing handlers,
* where each handler is responsible for taking the input and producing an
* output for the next handler in the chain. This mechanism of processing
* loosely conforms to the standard chain-of-responsibility design pattern

*             Client+             Proxy           Server+
*                              (nutcracker)
*                                   .
*       msg_recv {read event}       .       msg_recv {read event}
*         +                         .                         +
*         |                         .                         |
*         \                         .                         /
*         req_recv_next             .             rsp_recv_next
*           +                       .                       +
*           |                       .                       |       Rsp
*           req_recv_done           .           rsp_recv_done      <===
*             +                     .                     +
*             |                     .                     |
*    Req      \                     .                     /
*    ===>     req_filter*           .           *rsp_filter
*               +                   .                   +
*               |                   .                   |
*               \                   .                   /
*               req_forward-//  (1) . (3)  \\-rsp_forward
*                                   .
*                                   .
*       msg_send {write event}      .      msg_send {write event}
*         +                         .                         +
*         |                         .                         |
*    Rsp' \                         .                         /     Req'
*   <===  rsp_send_next             .             req_send_next     ===>
*           +                       .                       +
*           |                       .                       |
*           \                       .                       /
*           rsp_send_done-//    (4) . (2)    //-req_send_done
*
*
* (1) -> (2) -> (3) -> (4) is the normal flow of transaction consisting
* of a single request response, where (1) and (2) handle request from
* client, while (3) and (4) handle the corresponding response from the
* server.

好有愛的註釋!!

對應這段註釋的程式碼:

struct conn *
conn_get(void *owner, bool client, bool redis)
{
    struct conn *conn;

    conn = _conn_get();

    conn->client = client ? 1 : 0;

    if (conn->client) {
        
        conn->recv = msg_recv;
        conn->recv_next = req_recv_next;
        conn->recv_done = req_recv_done;

        conn->send = msg_send;
        conn->send_next = rsp_send_next;
        conn->send_done = rsp_send_done;

        conn->close = client_close;
        conn->active = client_active;

        conn->ref = client_ref;
        conn->unref = client_unref;

        conn->enqueue_inq = NULL;
        conn->dequeue_inq = NULL;
        conn->enqueue_outq = req_client_enqueue_omsgq;
        conn->dequeue_outq = req_client_dequeue_omsgq;
    } else {
        
        conn->recv = msg_recv;
        conn->recv_next = rsp_recv_next;
        conn->recv_done = rsp_recv_done;

        conn->send = msg_send;
        conn->send_next = req_send_next;
        conn->send_done = req_send_done;

        conn->close = server_close;
        conn->active = server_active;

        conn->ref = server_ref;
        conn->unref = server_unref;

        conn->enqueue_inq = req_server_enqueue_imsgq;
        conn->dequeue_inq = req_server_dequeue_imsgq;
        conn->enqueue_outq = req_server_enqueue_omsgq;
        conn->dequeue_outq = req_server_dequeue_omsgq;
    }

    conn->ref(conn, owner);

    return conn;
}

我們按照 messsage.c 裡面的4個步驟

後面的圖都採用這樣的表示方法:


初始狀態

考察只有一個後端的情況, 假設有2個client要傳送3個請求過來

相關推薦

twemproxy原始碼分析處理流程

很讚的註釋: * nc_connection.[ch] * Connection (struct conn) * + + + * |

Dubbo原始碼分析服務的呼叫

在呼叫服務之前,先得獲得服務的引用。 ReferenceBean 就是服務的引用。它實現了一個FactoryBean介面,在我們需要一個服務時,FactoryBean介面的getObject() 方法會被呼叫。 public Object getObje

HBase原始碼分析HRegion上compact流程分析(二)

  2016年03月03日 21:38:04 辰辰爸的技術部落格 閱讀數:2767 版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/lipeng_bigdata/article/details/50791205

以太坊的儲存層技術分析以太坊瘦身

前面一篇文章(分析之三)中提到了以太坊的資料儲存越來越大,有個資料“瘦身”的問題,本文中具體討論下。 以太坊是一個去中心化的區塊鏈系統,資料不是存放在中心伺服器上,而是存在客戶端的硬碟上。目前以太坊發展遇到一個現實問題:安裝過以太坊客戶端,挖過礦的同學想必都知道安裝完後同步

docker原始碼分析容器日誌處理與log-driver實現

子程序:由一個程序(父程序)建立的程序,整合父程序大部分屬性,同時可以被父程序守護和管理。 (2) 你需要知道關於程序產生日誌的形式: 程序產生

Spark原始碼分析Stage劃分

        Stage劃分的大體流程如下圖所示:         前面提到,對於JobSubmitted事件,我們通過呼叫DAGScheduler的handleJobSubmitted()方法來處理。那麼我們先來看下程式碼: // 處理Job提交的函式 pri

HBase原始碼分析HRegionServer上compact流程分析

        前面三篇文章中,我們詳細敘述了compact流程是如何在HRegion上進行的,瞭解了它的很多細節方面的問題。但是,這個compact在HRegionServer上是如何進行的?合併時檔案是如何選擇的呢?在這篇文章中,你將找到答案!         首先,在

Yarn原始碼分析MRAppMaster作業執行方式Local、Uber、Non-Uber

        基於作業大小因素,MRAppMaster提供了三種作業執行方式:本地Local模式、Uber模式、Non-Uber模式。其中,        1、本地Local模式:通常用於除錯;        2、Uber模式:為降低小作業延遲而設計的一種模式,所有任務,不

qemu原始碼分析--dyngen動態翻譯技術

    由於剛剛接觸qemu,所以前面幾篇文章僅僅是膚淺的介紹qemu的一些背景知識,今天突然感覺前面說的太沒有條理了,而且大部分是讀別人的文章,一知半解,沒有自己的總結體會,今天感覺稍微有點心得,敬請指教。 1. 明確guest和host     對於qemu而言,被模擬

ARChon 分析啟動流程分析

引文 通過前面幾篇文章的介紹,現在來看ARChon的js程式碼就簡單多了。基礎程式碼是 ARC 的執行環境。然後ChromeApp啟動,ChromeApp在配置項中配置了apk的路徑。然後呼叫 ARChon的擴充套件程式。開啟一個視窗。 那麼 ARChon 從哪裡看起呢? mai

LevelDB原始碼分析env

考慮到移植以及靈活性,LevelDB將系統相關的處理(檔案/程序/時間)抽象成Evn,使用者可以自己實現相應的介面,作為option的一部分傳入,預設使用自帶的實現。  env.h中聲明瞭: 虛基類env,在env_posix.cc中,派生類PosixEnv繼承自env

ABP原始碼分析Entity的設計

IEntity<TPrimaryKey>: 封裝了PrimaryKey:Id,這是一個泛型型別 IEntity: 封裝了PrimaryKey:Id,這是一個int型別 Entity<TPrimaryKey> :支援主鍵是泛型型別的Entity Entity:支援主鍵是int型別的

asihttp 原始碼分析 獲取請求進度

進度條相關的操作都定義在 ASIProgressDelegate .h 檔案中。 而且所有的方法都是optional的。 ipone上更新進度條的方法 :- (void)setProgress:(float)newProgress; #if TARGET_OS_IPHON

libjingle原始碼分析P2P

摘要         本文主要介紹了libjingle庫中的P2P模組。 概述         在libjingle中,P2P模組並非一個完全獨立的模組,它的實現依賴於Jingle協議,需要通過libjingle中的其它模組獲取必要的資訊和支援。P2P模組的內部結構及與

另闢蹊徑Ceph原始碼分析3解析ceph pg_temp(ceph 臨時pg)

什麼是pg_temp 假設一個PG通過crush演算法對映到的三個osd是[0,1,2],此時,如果osd0出現故障,導致crush演算法重新分配該PG的三個osd是[3,1,2],此時,osd3為該PG的主osd,但是osd3為新加入的osd,並不

雲客Drupal8原始碼分析響應附屬處理attachments_processor

在閱讀本主題前,你需要先閱讀本系列的渲染陣列、渲染器、渲染佔位符等主題 附屬物attachments就是渲染陣列的#attached部分,這裡稱為“附屬物”而不叫做“附件”,以便和圖片、檔案等概念相區別,附屬物有如下8個型別(以在#attached中的鍵名列出,如果添加了其

LevelDB原始碼分析skiplist(2)

閱讀本文可參考: LevelDB中的skiplist實現方式基本上和中的實現方式類似。它向外暴露介面非常簡單,如下: public: // Create a new SkipList object that will use "cmp" for compar

Spring Security原始碼分析Spring Social 社交登入的繫結與解綁

社交登入又稱作社會化登入(Social Login),是指網站的使用者可以使用騰訊QQ、人人網、開心網、新浪微博、搜狐微博、騰訊微博、淘寶、豆瓣、MSN、Google等社會化媒體賬號登入該網站。 前言 在之前的Spring Social系列中,我

memcached原始碼分析

還是從Memcached.c檔案的main函式開始,逐步分析Memcached的實現 if (!sanitycheck()) { return EX_OSERR; }static bool sanitycheck(void) { /*

小夥伴們的ceph原始碼分析三——monitor訊息處理流程

筆者在讀程式碼初期非常想理清楚的就是ceph這麼個系統在服務端與客戶端是怎麼響應與發起請求的。 本人主要負責monitor部分,而且追了一會cephx認證的程式碼,所以拿這塊舉例,後續osd部分主要是對同事分享的學習。 本篇會講到src/mon/monitor.cc中 c