基於Zmq的後台通訊模型介紹
- 2020 年 1 月 20 日
- 筆記
Zmq是一個簡單好用的傳輸組建,使得socket變成更加簡潔、高效、高性能。本文主要介紹後台服務實現、多執行緒任務實現、執行緒無鎖計數實現。
1.Zmq通常通訊模型
Zmq通訊場景:
- 執行緒之間(inproc)
- 進程之間(ipc)
- 機器之間(tcp)
Zmq通訊模式:
- 請求-回復(Request-reply)。分為ZMQ_REQ、ZMQ_REP、ZMQ_DEALER、ZMQ_ROUTER
- 發布-訂閱(Publish-subscribe)。分為ZMQ_PUB、ZMQ_SUB
- 管道(Pipeline)。分為ZMQ_PUSH、ZMQ_PULL
- 對立對(Exclusive pair)。分為ZMQ_PAIR
2.後台服務實現
多執行緒模式後台服務一般啟動一執行緒接收外部請求,再派發給工作執行緒進行處理請求,工作執行緒完成後返回給派發執行緒,最終返回請求方。
使用zmq執行緒間,請求-回復,ROUTER-DEALER模式可以很方便的實現多執行緒後台服務。實現原理如圖2-1。

1、Dispatcher執行緒通過tcp socket接收來自Client的請求。這裡tcp socket可以是基於zmq的tcp,也可以是普通的tcp請求,只要與client統一通訊協議即可,其中如果基於zmq則需要使用zmq的協議格式。
2、Dispatcher執行緒收到Client請求後採用zmq inproc socket派發給Worker執行緒。其中Dispatcher執行緒的zmq inproc socket採用DEALER模式。
3、Worker執行緒通過zmq inproc socket收到請求,進行處理,處理完後將結果返回給Dispatcher執行緒。Worker執行緒的zmq inproc socket採用ROUTER模式。
4、Dispatcher執行緒收到Worker執行緒的返回後將返回通過tcp返回給Client,完成一個完整的後台服務。
3 .多執行緒任務實現
很多後台任務並不是對外服務,僅僅是為了完成某項具體的任務,如數據處理、數據搬移、定時任務等。很多後台任務在多執行緒處理時,多任務需要在多執行緒完成,直接用鎖、共享資源來分配任務實現比較複雜,且容易出錯,如果採用zmq實現執行緒間通訊,其中一執行緒來派發任務,多執行緒循環完成任務。這種場景實現原理如圖3-1。

1.啟動一個Dispatcher執行緒進行任務派發;
2.Worker執行緒處理任務並返回處理結果;
3.Dispatcher執行緒統計結果,且繼續派發任務,這裡Dispatcher需要非同步來接收任務返回。
4.多執行緒無鎖計數實現
如果多個後台任務執行緒需要做一個互斥計數或取某一個數值,通常會想到直接用互斥鎖來實現,這裡基於zmq介紹一種通過執行緒間通訊來實現的方式。通過啟動一個Dispatcher來處理互斥資源操作,把操作結果返回給Worker執行緒,而這裡由於只有一個Dispatcher執行緒,能夠實現無鎖互斥效果。實現原理如圖4-1。

1.啟動一個Dispatcher執行緒進行操作需要互斥的資源,如計數等;
2.Worker執行緒發送請求給Dispatcher執行緒;
3.Dispatcher執行緒進行處理,處理完後返回給Worker執行緒。
5 .總結
Zmq本身是一個應用非常廣泛的通訊組建,這裡介紹的通訊模式在生產環境得到了充分的驗證,目前騰訊內部有基於zmq的成熟c++ rpc組件,本文主要講執行緒間的通訊,基於zmq多進程的模式實現後台框架,基本原理是一致的,可以進一步去研究。