[英]How would you grab the latest message from multiple connections to a single ZMQ socket?
我是 ZMQ 的新手,不確定我想要的是否可行,或者我是否應該使用其他技術。
我想要一個多個服務器可以流式傳輸到的套接字。
看來 ZMQ 套接字可以根據此文檔執行此操作: http ://api.zeromq.org/4-0:zmq-setsockopt
我將如何在接收端實現一個只獲取從每個服務器發送的最新消息的 ZMQ 套接字?
你可以用 Zmq 的 PUB / SUB 來做到這一點。
第一個關鍵是一個 SUB 套接字可以連接到多個 PUBlisher。 這在指南的第 1 章中有所介紹:
關於發布-訂閱(pub-sub)模式的一些要點:
訂閱者可以連接到多個發布者,每次使用一個連接調用。 然后數據將到達並交錯“公平排隊”,這樣就沒有一個發布者會淹沒其他發布者。
如果發布者沒有連接的訂閱者,那么它將簡單地丟棄所有消息。
如果您使用的是 TCP 而訂閱者速度很慢,則消息將在發布者上排隊。 稍后我們將研究如何使用“高水位線”來保護發布者免受這種情況的影響。
所以,這意味着您可以在客戶端上擁有一個 SUB 套接字。 這可以連接到多個 PUB 套接字,一個用於客戶端需要從中流式傳輸消息的每個服務器。
最新訊息
可以使用高水位線部分處理“最新消息”(正如我懷疑您已經開始發現的那樣)。 ZMQ_RCVHWM
選項允許將接收的數字設置為 1,盡管這是一個不精確的控制。
您還必須考慮“最新”消息的含義; PUB 服務器和 SUB 客戶端對此有不同的看法。 例如,當 PUB 服務器上的 zmq_send() 函數返回時,發送的消息是 PUBlisher 認為是“最新”的消息。
然而,在客戶端並不知道這一點,因為還沒有通過發布服務器的操作系統網絡堆棧,沒有任何東西接觸到以太網,等等。所以訂閱客戶端此時對“最新”消息的看法及時是 ZMQ 的內部緩沖區/隊列中等待應用程序讀取的消息。 與 PUBlisher 剛剛開始發送的消息相比,這條消息可能已經很舊了。
實際上,客戶端 SUBscriber 看到的“最新”消息將取決於 SUBscriber 應用程序運行的速度。
如果它足夠快以跟上所有 PUBlisher,那么 SUBscriber 收到的每條消息都將盡可能接近“最新”消息(消息將僅與網絡傳播延遲和所花費的時間一樣舊通過 ZMQ 的內部協議、緩沖區和隊列傳輸)。
如果 SUBscriber 的速度跟不上,那么它將看到的“最新”消息至少與每條消息的處理時間乘以 PUBlisher 的數量一樣舊。 如果您已將接收 HWM 設置為 1,並且訂閱者沒有跟上,發布者將嘗試發布消息,但訂閱者套接字將一直拒絕它們,直到訂閱的應用程序清除了導致隊列擁塞的舊消息,等待用於zmq_recv()
。
如果訂閱者跟不上,訂閱者最好的做法是:
有一個接收線程專用於接收消息並處理它們直到處理可用
有一個單獨的處理線程來進行處理。
讓兩個線程通過 ZMQ 進行通信,通過inproc
連接使用REQ
/ REP
模式。
接收線程可以zmq_poll
到 PUBlishing 服務器的 SUB 套接字連接和到處理線程的 REP 套接字連接。
如果接收線程在 REP 套接字上收到一條消息,它可以使用從 SUB 套接字讀取的下一條消息進行回復。
如果它從 SUB 套接字收到一條沒有到期 REPly 的消息,它就會處理該消息。
處理線程向其REQ套接字發送1字節的消息(內容無關緊要)以請求最新消息,並從PUBlisher接收最新消息作為回復。
或類似的東西。 這將使消息從 PUBlisher 流向 SUBscriber,因此 SUBscriber 總是有一條盡可能接近“最新”的消息,並盡可能地處理它,處理它無法處理的消息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.