2011-04-23 63 views
7

上下文:操作系統:Linux(Ubuntu),語言:C(實際上是Lua,但這應該不重要)。PUB/SUB與短命的發佈者和長期訂閱者

我寧願一個基於ZeroMQ的解決方案,但會接受任何足夠的理智。

注意:由於技術原因,我不能在這裏使用POSIX信號。

我在單臺機器上有幾個相同的長生命過程(「工人」)。

有時我需要通過命令行工具向每個進程發送控制消息。示例:

 
$ command-and-control worker-type run-collect-garbage 

本機上的每個工作人員都應該收到一條run-collect-garbage消息。 注意:如果解決方案以某種方式適用於羣集中所有機器上的所有工作人員,那將是完美的,但我可以自己編寫該部分。

如果我將存儲有關正在運行的工人的一些信息,這很容易完成。例如,將它們的PID保存在已知位置,並在已知路徑上打開一個控制Unix域套接字,並在其中包含PID。或者打開TCP套接字並在某處存儲主機和端口。

但是,這需要仔細管理存儲的信息 - 例如,如果工人突然死亡怎麼辦? (沒有什麼不可管理的,但仍然是額外的大驚小怪。)另外,信息需要存儲在某個地方,因此增加了一些額外的複雜性。

PUB/SUB風格有沒有很好的方法來做到這一點?也就是說,工作人員是訂戶,指揮和控制工具是一個發佈者,他們所知道的只是一個單一的「渠道網址」,可以這麼說,用來發送消息。

附加要求:

  • 消息給控制信道必須從輪詢醒來工人(選擇,無論) 迴路。
  • 消息傳遞必須得到保證,並且它必須到達每個正在傾聽的工作人員。
  • 工作人員應該有一種方法來監視消息沒有阻塞 - 理想情況下通過上面提到的poll/select/whatever循環。
  • 理想情況下,從某種意義上講,工作進程應該是「服務器」 - 他不應該爲保持與「通道服務器」(如果有)持續連接等問題擔憂 - 或者應該由框架透明地完成。

回答

3

通常這樣的模式需要發佈者的代理,即您發送到代理,該代理立即接受交付,然後可靠地向最終的訂戶工作者傳播。 ZeroMQ指南涵蓋了實現這一點的幾種不同方法。

http://zguide.zeromq.org/page:all

+1

另一個可能有用的東西,我發現當做搜索時,發現我這個問題:http://code.google.com/p/ops/ - 我沒有使用它,因此不能說只要將它添加爲評論,以免發現zmq以任何方式缺乏。 – lindes 2013-10-28 18:49:46

0

我想你所描述的將適合於一個gearmand/supervisord實現。

Gearman是一個很棒的任務隊列管理器,supervisord可以讓你確保所有進程都在運行。它也是基於TCP的,所以你可以讓客戶/工作人員在不同的機器上。

http://gearman.org/

http://supervisord.org/

我最近一些設置有多個gearmand節點,鏈接到多個工人,以便有沒有單故障點

編輯:對不起 - 我的壞,我只是重新閱讀,看到這可能不理想。

Redis有一些不錯的和簡單的外觀/子功能,我還沒有使用,但聽起來很有希望。

+0

Redis PUB/SUB不適用於我 - 無法在其中執行非阻塞讀取操作,並且我有權訪問的客戶端不會公開原始套接字以放置輪詢/選擇循環。 – 2011-04-23 15:59:00

0

使用多播PUB/SUB。您必須確保pgm選項已編譯到您的ZeroMQ發行版(man 7 zmq_pgm)中。

+0

多播在我的VPS服務器上不起作用。 :-( – 2011-04-29 07:44:34

2

考慮您的要求,史蒂夫的建議確實顯得簡單:運行監聽的兩個已知套接字守護 - 工人們連接到和命令工具推到它該重新分配給連接的工人。

通過有效提名其中一名工作人員,您可以做一些複雜的工作。例如,在啓動時,工作人員嘗試將某個PUB ipc://套接字綁定到某處(如tmp)。一個將bind()作爲第二個IPC作爲PULL套接字,並作爲正常職責之上的轉發器設備,其他IPC連接()到原始IPC。命令行工具connect()到第二個IPC,並推送它的消息。有贏家死亡的風險,留下一個鎖定的文件。你可以在命令行工具中識別這個,重新綁定然後休眠(以允許建立連接)。儘管如此,這有點複雜,我想我會使用代理服務器!

相關問題