7

上下文:操作系统:Linux(Ubuntu),语言:C(实际上是 Lua,但这不重要)。

我更喜欢基于 ZeroMQ 的解决方案,但会接受任何足够理智的东西。

注意:由于技术原因,我不能在这里使用 POSIX 信号。

我在一台机器(“工人”)上有几个相同的长期进程。

有时我需要通过命令行工具向每个进程传递控制消息。例子:

$ 命令和控制工人类型运行收集垃圾

这台机器上的每个工人都应该收到一条run-collect-garbage消息。注意:如果解决方案能以某种方式适用于集群中所有机器上的所有工作人员,那将是完美的,但我可以自己编写这部分。

如果我要存储一些关于运行工作者的信息,这很容易做到。例如,将它们的 PID 保存在已知位置,并在已知路径上打开一个控制 Unix 域套接字,其中某处有 PID。或者打开 TCP 套接字并将主机和端口存储在某处。

但这需要仔细管理存储的信息——例如,如果工作进程突然死亡怎么办?(没有什么是无法管理的,但仍然需要大惊小怪。)此外,信息需要存储在某个地方,从而增加了额外的复杂性。

有没有一种以 PUB/SUB 风格执行此操作的好方法?也就是说,工作人员是订阅者,命令和控制工具是发布者,他们所知道的只是一个“频道 url”,可以说是用来获取消息的。

其他要求:

  • 发送到控制通道的消息必须从轮询(选择,无论如何)循环中唤醒工作人员。
  • 必须保证消息传递,并且必须到达每一个正在收听的工作人员。
  • Worker 应该有一种方法可以在不阻塞的情况下监控消息——最好是通过上面提到的 poll/select/whatever 循环。
  • 理想情况下,工作进程在某种意义上应该是“服务器”——他不应该为保持与“通道服务器”(如果有的话)持久连接等而烦恼——或者这应该由框架透明地完成。
4

4 回答 4

4

通常这种模式需要发布者的代理,即您发送到代理,该代理立即接受交付,然后可靠地转发给最终订阅者工作人员。ZeroMQ 指南涵盖了几种不同的实现方法。

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

于 2011-05-17T19:32:03.480 回答
2

鉴于您的要求,Steve 的建议似乎是最简单的:运行一个监听两个已知套接字的守护进程 - 工作人员连接到该套接字,命令工具推送到它并重新分配给连接的工作人员。

通过有效地提名一名工人,你可以做一些可能会奏效的复杂事情。例如,在启动时,工作人员尝试在可访问的某个地方绑定()一个 PUB ipc:// 套接字,例如 tmp。赢得bind()第二个IPC作为PULL套接字并在其正常职责之上充当转发器设备的那个,其他的connect()到原始IPC。命令行工具 connect()s 到第二个 IPC,并推送它的消息。存在获胜者死亡的风险,留下一个锁定的文件。您可以在命令行工具中识别它,重新绑定然后休眠(以允许建立连接)。不过,这有点复杂,我想我会选择代理!

于 2011-06-28T14:43:11.163 回答
0

我认为您所描述的内容很适合 gearmand/supervisord 实现。

Gearman 是一个很棒的任务队列管理器,supervisord 可以让你确保所有的进程都在运行。它也是基于 TCP 的,因此您可以在不同的机器上拥有客户端/工作人员。

http://gearman.org/

http://supervisord.org/

我最近设置了多个 gearmand 节点,链接到多个工人,这样就没有单点故障

编辑:对不起-我的错,我只是重新阅读并发现这可能并不理想。

Redis有一些漂亮而简单的 pub/sub 功能,我还没有使用过,但听起来很有希望。

于 2011-04-23T15:51:16.757 回答
0

使用多播 PUB/SUB。您必须确保该pgm选项已编译到您的 ZeroMQ 发行版中 ( man 7 zmq_pgm)。

于 2011-04-28T23:21:27.027 回答