环境:操作系统:Linux (Ubuntu),语言:C(实际上是Lua,但这应该无关紧要)。
我更喜欢基于zeromq的解决方案,但也会接受任何足够合理的解决方案。
注意:由于技术原因,我不能在这里使用POSIX信号
我在一台机器上有几个相同的长寿命进程("worker ")。
不时地,我需要通过命令行工具向每个进程传递控制消息。例子:
<>之前$ command-and-control worker-type运行-collect-garbage之前这台机器上的每个工人都应该收到一条run-collect-garbage
消息。注意:如果解决方案在某种程度上适用于集群中所有机器上的所有工作人员,那将是完美的,但我可以自己编写这部分。
如果我存储一些关于运行工人的信息,这很容易做到。例如,将它们的PID保存在已知位置,并在已知路径上打开一个控制Unix域套接字,其中某处有一个PID。或者打开TCP套接字,在某处存储主机和端口。
但是这需要小心地管理存储的信息——例如,如果工作进程突然死亡怎么办?(没有什么难以管理的,但是,仍然是额外的麻烦。)此外,信息需要存储在某个地方,从而增加了额外的复杂性。
在PUB/SUB风格中是否有一个好的方法来做到这一点?也就是说,工人是订阅者,命令和控制工具是发布者,他们所知道的只是一个单一的"通道url",也就是说,从哪个渠道来获取消息。
附加要求:
- 发送到控制通道的消息必须从轮询中唤醒工作线程(select,等等)循环。
- 消息传递必须得到保证,并且必须到达每个正在侦听的worker。
- Worker应该有一种不阻塞地监视消息的方法-理想情况下是通过上面提到的poll/select/whatever循环。
- 理想情况下,工作进程在某种意义上应该是"服务器"——他不应该为保持与"通道服务器"(如果有的话)的连接而烦恼——或者这应该由框架透明地完成。
通常这种模式需要发布者的代理,即您发送到立即接受交付的代理,然后可靠地转发给最终订阅者工作者。ZeroMQ指南涵盖了实现此功能的几种不同方法。
http://zguide.zeromq.org/page:
考虑到您的需求,Steve的建议似乎是最简单的:运行一个监听两个已知套接字的守护进程——工人连接到它,命令工具推送到它,它重新分配给连接的工人。
你可以通过有效地提名其中一个工人来做一些可能有效的复杂事情。例如,在启动时,工作者尝试绑定()PUB ipc://套接字,例如tmp。赢得bind()的是作为PULL套接字的第二个IPC,并在其正常职责之上充当转发器设备,其他的连接()到原始IPC。命令行工具connect()s连接到第二个IPC,并推送它的消息。这样做的风险是赢家死了,留下一个被锁定的文件。您可以在命令行工具中识别它,重新绑定然后休眠(以允许建立连接)。不过,这有点复杂,我想我还是用代理吧!
我认为你所描述的很适合一个装备/监督系统的实现。
Gearman是一个很棒的任务队列管理器和监督器,它允许您确保所有进程都在运行。它也是基于TCP的,所以你可以在不同的机器上有客户端/工作器。
http://gearman.org/http://supervisord.org/我最近设置了多个设备节点,链接到多个工作人员,这样就没有单点故障
编辑:对不起-我的错,我只是重新阅读,看到这可能不是理想的
Redis有一些不错的和简单的pub/sub功能,我还没有使用过,但听起来很有希望。
使用多播PUB/SUB。您必须确保将pgm
选项编译到您的ZeroMQ发行版(man 7 zmq_pgm
)中。