使用libevent和多線程構建高性能服務器(客戶端)

有問題可以聯繫我[email protected]

    因爲開發數據庫集羣,節點需要通信,必須構建基於socket的C++網絡通信系統。多年前使用UPD寫過P2P流媒體,但是現在需要TPC,首先使用了Nanomsg作爲網絡庫,但是開發過程中發現其不靠譜(模式太單一,並且出了問題根本找不到解決辦法)。於是又掉頭回來使用原生的socket編程。發現目前比較流行的(C++)網絡編程使用libevent或者libev,通過調研感覺libevent成熟一些,於是選擇了libevent。

    下面說一下在我們數據庫集羣中對網絡通信的使用模式:

1. 每個節點既是客戶端又是服務器

2. 每個節點互相簡歷長連接(短連接的話,每次通信都要建立連接代價太高)

3. 節點之間發送消息使用rpc方式,因此選用了google的protobuf

4. 多線程服務模式,即每個消息都由不同的線程處理,這樣複雜的消息也不會阻塞後面的消息。

    綜上,我使用的是libevent+protobuf+pthread。libevent可以構建基於回調函數的socket網絡庫,protobuf提供rpc,pthread和libevent一起工作提供多線程方式。也可以使用std::thread,但是libevent默認支持的是pthread,你也可以在libevent中實現支持std::thread的函數,但是保險期間我還是用了pthread。下面舉個具體的例子來說一下工作流程:

例如集羣有10個節點,每一個節點都會和其他9個節點進行長連接,即每個節點都由9個socket,對應libevent有9個bufferevent,這9個bufferevent放入到一個eventbase裏由主線程進行dispatch。每個bufferevent都有一個readcaback函數,主要這個bufferevent有消息到達,readcallback 就會被觸發讀取相應的消息,在read callback中把該消息丟到線程池中去處理:

    線程池會分配一個線程解析消息內容,然後調用protobuf的rpc方法,rpc方法處理完會產生一個response消息,該線程再把該response消息發送回去。

    客戶端接收到response會觸發read callback,因爲客戶端實際上也是服務端,所以處理流程也是一樣的,read callback會把response消息丟給線程池,線程池在調用一個線程處理該response。

    具體代碼請見github:https://github.com/cmu-db/peloton/tree/master/src/backend/networking

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章