1 ZeroMQ概述算法
ZeroMQ是一種基於消息隊列的多線程網絡庫,其對套接字類型、鏈接處理、幀、甚至路由的底層細節進行抽象,提供跨越多種傳輸協議的套接字。ZeroMQ是網絡通訊中新的一層,介於應用層和傳輸層之間(按照TCP/IP劃分),其是一個可伸縮層,可並行運行,分散在分佈式系統間。服務器
2 系統架構網絡
2.1整體架構多線程
ZeroMQ幾乎全部的I/O操做都是異步的,主線程不會被阻塞。ZeroMQ會根據用戶調用zmq_init函數時傳入的接口參數,建立對應數量的I/O Thread。每一個I/O Thread都有與之綁定的Poller,Poller採用經典的Reactor模式實現,Poller根據不一樣操做系統平臺使用不一樣的網絡I/O模型(select、poll、epoll、devpoll、kequeue等)。主線程與I/O線程經過Mail Box傳遞消息來進行通訊。Server開始監聽或者Client發起鏈接時,在主線程中建立zmq_connecter或zmq_listener,經過Mail Box發消息的形式將其綁定到I/O線程,I/O線程會把zmq_connecter或zmq_listener添加到Poller中用以偵聽讀/寫事件。Server與Client在第一次通訊時,會建立zmq_init來發送identity,用以進行認證。認證結束後,雙方會爲這次鏈接建立Session,之後雙方就經過Session進行通訊。每一個Session都會關聯到相應的讀/寫管道, 主線程收發消息只是分別從管道中讀/寫數據。Session並不實際跟kernel交換I/O數據,而是經過plugin到Session中的Engine來與kernel交換I/O數據。架構
圖1整體架構 併發
2.2所處層次 負載均衡
ZeroMQ不是單獨的服務或者程序,僅僅是一套組件,其封裝了網絡通訊、消息隊列、線程調度等功能,向上層提供簡潔的API,應用程序經過加載庫文件,調用API函數來實現高性能網絡通訊。 異步
圖2所處層次 tcp
2.3消息模型 分佈式
ZeroMQ將消息通訊分紅4種模型,分別是一對一結對模型(Exclusive-Pair)、請求迴應模型(Request-Reply)、發佈訂閱模型(Publish-Subscribe)、推拉模型(Push-Pull)。這4種模型總結出了通用的網絡通訊模型,在實際中能夠根據應用須要,組合其中的2種或多種模型來造成本身的解決方案。
2.3.1 一對一結對模型
最簡單的1:1消息通訊模型,能夠認爲是一個TCP Connection,可是TCP Server只能接受一個鏈接。數據能夠雙向流動,這點不一樣於後面的請求迴應模型。
2.3.2 請求迴應模型
由請求端發起請求,而後等待迴應端應答。一個請求必須對應一個迴應,從請求端的角度來看是發-收配對,從迴應端的角度是收-發對。跟一對一結對模型的區別在於請求端能夠是1~N個。該模型主要用於遠程調用及任務分配等。Echo服務就是這種經典模型的應用。
圖3請求迴應模型
2.3.3 發佈訂閱模型
發佈端 單向分發數據,且不關心是否把所有信息發送給訂閱端。若是發佈端開始發佈信息時,訂閱端還沒有鏈接上來,則這些信息會被直接丟棄。訂閱端未鏈接致使信息丟失 的問題,能夠經過與請求迴應模型組合來解決。訂閱端只負責接收,而不能反饋,且在訂閱端消費速度慢於發佈端的狀況下,會在訂閱端堆積數據。該模型主要用於 數據分發。天氣預報、微博明星粉絲能夠應用這種經典模型。
圖4發佈訂閱模型
2.3.4 推拉模型
Server端做爲Push端,而Client端做爲Pull端,若是有多個Client端同時鏈接到Server端,則Server端會在內部作一個負載均衡,採用平均分配的算法,將全部消息均衡發佈到Client端上。與發佈訂閱模型相比,推拉模型在沒有消費者的狀況下,發佈的消息不會被消耗掉;在消費者能力不夠的狀況下,可以提供多消費者並行消費解決方案。該模型主要用於多任務並行。
圖5 推拉模型
2.4通訊協議
提供進程內、進程間、機器間、廣播等四種通訊協議。通訊協議配置簡單,用相似於URL形式的字符串指定便可,格式分別爲inproc://、ipc://、tcp://、pgm://。ZeroMQ會自動根據指定的字符串解析出協議、地址、端口號等信息。
3 工做流程
圖6 基本流程
4 性能分析
目前,市面上相似的產品很多,主要有4種:MSMQ(微軟產品)、ActiveMQ(Java)、RabbitMQ(Erlang)、ZeroMQ(C++)。除ZeroMQ外,其它3款產品都是一個單獨服務或者進程,須要單獨安裝和運行,且對環境有必定依賴。其中,MSMQ在非Windows平臺下安裝很是複雜,ActiveMQ須要目標機器上已經安裝了Java,RabbitMQ須要Erlang環境。而ZeroMQ是以庫的形式存在,由應用程序加載、運行便可。可是ZeroMQ僅提供非持久性的消息隊列。
圖7是來自於Internet的性能測試數據。顯示的是每秒鐘發送和接受的消息數。整個過程共產生1百萬條1K的消息,測試環境爲Windows Vista。從測試數據能夠看出,ZeroMQ的性能遠遠高於其它3個MQ。
可是測試數據僅供參考,由於缺乏必須的環境參數和性能指標,好比:CPU參數、內存參數、消息模型、通訊協議、極限時消耗CPU百分比、極限時消耗內存百分比等。
圖7性能測試
5 應用場景
應用ZeroMQ的Push-Pull模型實現聯衆遊戲服務器的「熱插拔」、負載均衡和消息派發。按照如圖8部署服務器,Push端充當Gateway,做爲一組遊戲服務器集羣最上層的一個Proxy,起負載均衡的做用,全部Gameserver做爲Pull端。當一個請求到達Push端(Gateway)時,Push端根據必定的分配策略將任務派發到Pull端(Gameserver)。以聯衆某款遊戲A爲例,遊戲A剛上線時,預計最大同時在線人數是10W,單臺Gameserver併發處理能力爲1W,須要10臺Gameserver,因爲遊戲A可玩性很是好,半個月後最大同時在線人數暴增到50W,那麼不須要在某天的凌晨將Gateway和Gameserver停機,只須要隨時在機房新添加40臺Gameserver,啓動並鏈接到Gateway便可。
ZeroMQ中對Client和Server的啓動順序沒有要求,Gameserver之間若是須要通訊的話,Gameserver的應用層不須要管理這些細節,ZeroMQ已經作了重連處理。
圖8應用場景
6 總結
6.1簡單
1、僅僅提供24個API接口,風格相似於BSD Socket。
2、處理了網絡異常,包括鏈接異常中斷、重連等。
3、改變TCP基於字節流收發數據的方式,處理了粘包、半包等問題,以msg爲單位收發數據,結合Protocol Buffers,能夠對應用層完全屏蔽網絡通訊層。
4、對大數據經過SENDMORE/RECVMORE提供分包收發機制。
5、經過線程間數據流動來保證同一時刻任何數據都只會被一個線程持有,以此實現多線程的「去鎖化」。
6、經過高水位HWM來控制流量,用交換SWAP來轉儲內存數據,彌補HWM丟失數據的缺陷。
7、服務器端和客戶端的啓動沒有前後順序。
6.2靈活
1、支持多種通訊協議,能夠靈活地適應多種通訊環境,包括進程內、進程間、機器間、廣播。
2、支持多種消息模型,消息模型之間能夠相互組合,造成特定的解決方案。
6.3跨平臺
支持Linux、Windows、OS X等。
6.4多語言
能夠綁定C、C++、Java、.NET、Python等30多種開發語言。
6.5高性能
相對同類產品,性能卓越。