Linux上的一对多进程间通信
我有一个“服务器”进程,它生成一些日志。我希望用户(或其他服务)能够查看该日志流(如Linux上的一对多进程间通信,linux,sockets,Linux,Sockets,我有一个“服务器”进程,它生成一些日志。我希望用户(或其他服务)能够查看该日志流(如tail-f),但我不想将这些日志写入文件系统。我可以在Linux上这样做吗 我的第一次尝试是在环回接口上使用UDP。服务器将数据包发送到端口12345上的本地主机,客户端可以绑定到该端口以接收数据包。不起作用。因为只有一个客户端可以绑定到同一个套接字。啊!!但是您可以说use SO_REUSE_ADDR,它允许两个客户端绑定到一个端口,但只有一个客户端接收消息 接下来,我在环回接口上尝试了UDP多播。这一点还没
tail-f
),但我不想将这些日志写入文件系统。我可以在Linux上这样做吗
ifconfig
:
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:186 errors:0 dropped:0 overruns:0 frame:0
TX packets:186 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:11904 (11.6 KiB) TX bytes:11904 (11.6 KiB)
注意上面缺少多播
(或者广播
)如果有什么不同的话,我会用Python来完成所有这些工作。我可以想出两种通用方法 1) 使用POSIX共享内存对象 有关更多信息,请参阅shm_open(3)手册页面 您的应用程序将创建一个共享内存对象,它将在其中写入日志消息,任何客户端应用程序都可以打开共享内存对象并读取它。尽管POSIX共享内存API看起来像是基于文件系统的API,但事实并非如此 现在,请记住,您将只获得一块内存,大小符合您的要求。您必须弄清楚应用程序将如何构造,并以某种有意义的方式管理这段内存,以便您的客户端应用程序能够解析并轮询更改的内容 (二) 您的应用程序承担着打开和侦听任何客户端都可以连接的本地主机套接字或文件系统域套接字的负担,并且您的应用程序只需将其日志消息写入当前存在的每个客户端连接
这有点棘手。您的应用程序需要能够不断地接受来自客户端的新连接,无论它们何时进入,向所有并发连接写入消息,检测某个客户端何时卡住,不从其套接字末端读取,从而使本地套接字内部缓冲区满,因此,阻塞写入将阻塞并挂起主应用程序;因此,所有写入必须是非阻塞权限,应用程序将自动关闭任何已满的套接字,等等。。。等等等。您可以看看ZeroMQ。您所描述的是对发布者/订阅者模式的需求,这正是ZeroMQ非常优雅地做的事情。它还有一个额外的优点,那就是在下面使用何种交通工具时非常灵活;IPC、TCP等,这使得将程序的某些部分放到网络上的其他位置变得非常简单。使用ZeroMQ,您将得到非常简单的源代码,其复杂性都隐藏在zmq库中。你可以先看一下这个部分
你也可以考虑NanoMSG(即将到来的ZrOMQ做得更好),虽然我还不确定是否有Python绑定。
看一下,流行的解决方案是ReISIS。
他们都有python客户端 在你的第一段中提出了一个问题:如果你只能实时阅读日志,那么日志有什么用?什么不放在文件中?它基本上需要一个轮询循环(
select
,poll
,epoll
)运行,以连接到客户端,维护活动客户端列表,并在生成最新日志后立即将其发送给它们。可能最好使用管道将日志从主服务器通过管道传递到辅助tcp/udp服务器,并在那里进行循环。这看起来是一个很好的解决方案。我一直错误地认为ZeroMQ使用了代理进程!而且PUB套接字类型不会阻塞。我会进一步调查…@joerick,是的,经纪人少是好的。作为记录,数据分发服务也是无代理的。RabbitMQ有一个代理,人们想知道当代理中断时会发生什么。在ZeroMQ中,有线程在后台运行,完成所有工作,但最终的结果是,它们对整个系统的运行都不是关键的。一个坏了,其他一切都在继续,希望如此。重新启动坏的,一切正常。