2013-08-20 66 views
12

我正在爲中型系統測試ZeroMQ作爲Pub-Sub(服務總線樣式)。 我們有大約50個節點,它們都應該是發佈者和訂閱者。網絡是一種星型拓撲結構,但邊緣彼此「交談」。 我們需要動態發現(不需要硬編碼參與者的網絡地址),也不需要SPOF(單點故障)。ZeroMQ Pub-Sub +沒有調解器的動態發現

我已閱讀http://zeromq.org/whitepapers:0mq-3-0-pubsub,據我所知,動態發現的0MQ建議方式涉及轉發訂閱和發佈的代理節點(XPUB/XSUB)。 我認爲使用這樣的代理在我們的系統中的重要介質,但是,我有這個架構如下擔憂: (A)代理節點是SPOF - 當它發生故障,整個系統不能正常工作 (B)包括數據在內的所有流量均通過代理節點,這意味着延遲性能問題&。

假設我理解正確的發佈 - 訂閱白皮書,是有實現的發佈 - 訂閱+動態發現+在ZeroMQ無SPOF一個比較簡單的方法是什麼?

附加一點:我已經排除了多播(PGM)解決方案,因爲大多數消息具有單個/幾個利益相關方,我們不希望過度擁擠的網絡。

回答

8

由於用戶可以直接與發佈者交談,所以具有單個發佈者的多個訂閱者不需要中介。但許多出版商和訂閱者同時並不那麼容易;除非中間有什麼東西,否則維護將是一場噩夢,因爲新用戶必須配置所有現有的發佈者。

你可以部署多個XSUB/XPUB代理,每一個自己的機器上,然後部署出版商和代理人之間的負載均衡(如F5)。這實現了上游側的負載平衡和容錯。

代理代碼很簡單:

Socket frontend = context.socket(ZMQ.XSUB); 
frontend.bind("tcp://proxy1:5444"); 
Socket backend = context.socket(ZMQ.XPUB); 
backend.bind("tcp://proxy1:5555"); 
frontend.subscribe("".getBytes()); 
ZMQ.proxy (frontend, backend, null); 

如果代理節點發生故障,只需重新啓動;重新連接/訂閱應由zmq自動處理。

對於下游用戶,直接連接每個用戶到所有可用的代理服務器:

subscriber = ctx.createSocket(ZMQ.SUB) 
subscriber.connect("tcp://proxy1:5555") 
subscriber.connect("tcp://proxy2:5555") 
subscriber.connect("tcp://proxy3:5555") 

出版商將此起彼伏往往比代理,因爲代理的數量,以便直接連接用戶到代理導致更少的配置維護將大部分是靜態的。

如果代理節點發生故障,則上游LTM會相應地將流量路由到剩餘的代理節點;用戶將不會受到影響,因爲他們從所有可用的代理消費。

慢訂戶可以與同步來解決,在this閱讀起來。
檢出訂閱並將網絡流量減至最小here

enter image description here

+0

其實我不明白,在提出的解決方案的東西:當任何用戶簽約的,在循環賽DNS將重定向訂閱消息的一些LTM,將其重定向到一些(單?)代理這將持有訂閱。如果此代理機器崩潰,訂閱將會丟失,不是嗎? – dux2

+0

謝謝。在此解決方案中,如何避免在每個代理中靜態配置發佈者列表?你如何處理遲到的出版商?我可以想象一個發佈者在啓動時向每個代理「宣佈」它的存在,然後代理將所有訂閱發送給新的發佈者。代理如何從崩潰中恢復?它必須要求所有訂閱者重新訂閱或持續訂閱。 這是完全可能的,但需要編寫很多代碼,就像從頭開始開發自己的pub-sub一樣。 – dux2

+0

再次更新,希望它有幫助。 – raffian