ZeroMQ
.我正在使用PHP来写入客户端和服务器.这主要用于处理推送通知.
正如他们已经证明的那样,我正在使用单一的I / O线程的ZMQContext实例上的基本REQ
–REP
正式通信模式.
include("someFile.PHP"); $context = new ZMQContext(1); // Socket to talk to clients $responder = new ZMQSocket($context,ZMQ::SOCKET_REP); $responder->bind("tcp://*:5555"); while (true) { $request = $responder->recv(); printf ("Received request: [%s]\n",$request); // ----------------------------------------------------------------- // Process push notifications here // sleep (1); // ----------------------------------------------------------------- // Send reply back to client $responder->send("Basic Reply"); }
这里是一个最小化的ZeroMQ客户端:
$context = new ZMQContext(); // Socket to talk to server echo "Connecting to hello world server…\n"; $requester = new ZMQSocket($context,ZMQ::SOCKET_REQ); $check = $requester->connect("tcp://localhost:5555"); var_dump($check); $requester->send("json string payload with data required to process push notifications."); //$reply = $requester->recv();
那么,我做什么?我使用linux命令运行zeromqServer.PHP作为后台服务
这将作为后台进程运行.现在,当客户端调用它时,它执行所需的作业.
但问题是,我需要重新启动该过程,每次任何文件(包括在zeromqServer文件中包含的文件)发生变化.
而且,不管怎样,2-3天后,它只是停止工作.该过程不会停止,但它只是停止工作.
我觉得它一定是一些socket问题,也许socket不再打开了.那时候我必须重新启动zeromqServer.PHP文件进程.
Q1:可能是什么问题?
Q2:这样做的正确方法是什么?
A1:问题是您的服务器最终必须阻止,因为客户端代码在REQ / REP模式需要这样做时才能检索任何答案. REP侧的zeromqServer.PHP将不会尝试从客户端(在正式通信缓冲区的REQ端)recv()另一个消息,直到客户端被物理传送(内部缓冲区)并具有recv( ) – 来自zeromqServer.PHP端的“reply”-message.
ZeroMQ的早期版本,ver. 2.1数据被复制到O / S内核中之前,已经使用了一个节点的内部消息队列和内存管理的无限制,无限大的默认限制,用于低级I / O线程缓冲.资源,并从ZeroMQ内存发布.
较新版本的ZeroMQ,ver 3.x,默认情况下具有所谓的HWM-s(又称High-Water-Mark-s)“只”1000个消息为“short”的消息,之后,这些ZeroMQ资源的相应部分开始阻止或删除邮件.
虽然显式增加HWM设置管理的反应性尝试看起来像一个肮脏的方法来解决主设计错误,但是另一个ZeroMQ警告在这方面是公平的,以便进一步谨慎地朝这个方向前进(ØMQ不保证套接字将接受为许多作为ZMQ_SNDHWM消息,并且根据套接字上的消息流量,实际限制可能会降低多达60-70%).
忘记或无法做到这一点(参考:OP代码已经展示):
//$reply = $requester->recv();
意味着您的REQ / REP正式通信模式“摆”成为不可逆转的僵局(永远).
A2:基本REQ / REP正式通信 – 模式听起来很直观,但有一些危险的特征,观察到的阻塞只是其中之一.部署XREQ / XREP,DEALER / ROUTER等工具可能需要采取一些额外的步骤,但是应该修改设计,而不仅仅是SLOC的SLOC,因为似乎有很多事情要实现,在设计代码之前.一个主要的错误之一是假定一个send()方法已经被命令发送一个消息. ZeroMQ并非如此.代码设计也应该假定消息传递的不确定性,正确地处理丢失的消息问题和任何类型的分布式服务阻塞事件(死锁,活动锁定,缓冲区阈值溢出,旧/新API冲突等)没有任何明确的保证您的消息传递对等体(ZeroMQ中没有中央消息代理)具有与其本地主机端实现的相同版本的ZeroMQ API /协议 – 所以确实有很多新的观点代码设计)
最好的方式来做到这一点
如果您能信任并相信一个实践经验,您最好的下一步应该是下载并阅读fabulous Pieter HINTJENS’ book "Code Connected,Volume 1"
,其中Pieter对分布式处理有很多见解,包括许多提示和可靠模式的指示,就像你想实现的那样.
阅读这本书,这是值得你的时间,如果你留在分布式软件设计,你可能会多次重读这本书,所以不要犹豫,立即开始从大师大师跳到这样一本400页的食谱,Pieter HINTJENS出来的问题是.
为什么?现实世界通常要复杂得多
只需一张照片,从上述图中可以看出,图60中忽略了个人原型的重用,并意识到需要一个适当的端到端分布式系统设计视角.阻塞避免和僵局解决策略:
只需要有一些想法,请查看以下代码示例,从简单的分布式消息传递,其中aMiniRESPONDER进程使用多个ZeroMQ通道.
如何在相当大的Web应用程序域中改进实现?
了解如何同时防止(设计上)和处理(deux-ex-machina类型)其他冲突.PHP已经拥有这种类型的算法的所有正确的语法构造器,但是架构和设计在你手中,从头到尾.
只需要意识到,一个ZeroMQ信令基础架构设置/系统部分/ ZeroMQ格式终止工作的碰撞感知{try :,except :,finally:}风格有多大,只需按行号检查[SoW]:
14544 - 14800 // a safe infrastructure setup on aMiniRESPONDER side ~ 256 SLOCs 15294 - 15405 // a safe infrastructure gracefull termination ~ 110 SLOCs
与aMiniRESPONDER示例的事件处理段的核心逻辑相比
14802 - 15293 // aMiniRESPONDER logic,incl. EXC-HANDLERs ~ 491 SLOCs
基于ZeroMQ的分布式系统的最终奖励
苛刻?是的,但非常强大,可扩展,快速&确实有益于正确使用.不要犹豫投资你的时间&努力获取和管理您在这个领域的知识.您所有进一步的软件项目都可能受益于此专业投资.