我一直在使用ZeroMQ的请求/响应套接字来在用于卸载处理的web应用程序和从应用程序之间交换消息。我注意到,在一些情况下,并不是所有发送的ZMQ消息都是由另一方接收的。甚至奇怪的是,即使在IPC协议中也会发生这种情况,我认为这是相当可靠的。
在没有产生任何错误的情况下,什么才能对未发送的消息负责?
下面是客户端代码的一个示例:
# ironic
class ReliableClient(object):
def _reconnect(self):
if self.socket:
self.socket.close()
self.socket = None
self.socket = self.context.socket(zmq.REQ)
self.socket.connect(self.server_url)
# Give the server 2 sec to respond
self.socket.RCVTIMEO = 2000
self.socket.SNDTIMEO = 2000
self.socket.LINGER = 3
def __init__(self, server_url=None, server_name=None):
self.socket = None
self.server_url = server_url
if server_name is None:
self.server_name = server_url
else:
self.server_name = server_name
self.lock = threading.Lock()
self.context = zmq.Context()
self._reconnect()
def msg(self, msg):
raw_out = dumps(msg)
# send
self.lock.acquire()
try:
self.socket.send(
raw_out,
copy=True
)
except zmq.ZMQError as ex:
log.exception(ex, '%s: failed to send', self.server_name)
self.lock.release()
raise CommunicationError('failed to send')
# receive
try:
raw_in = self.socket.recv()
except zmq.ZMQError as ex:
log.exception(ex, '%s: failed to receive', self.server_name)
raise CommunicationError('failed to receive')
finally:
self.lock.release()
msg_in = loads(raw_in)
return msg_in发布于 2013-08-15 17:59:34
我不熟悉IPC协议,但我已经广泛地使用了ZMQ/TCP。
即使是最简单的TCP 上的ZMQ /REP模式,如果使用得当,也永远不会丢弃消息。如果网络连接或远程端点出现故障,它可能会无限期挂起,但绝不会默默地失败。在某些情况下,某些套接字会按设计丢弃消息。例如,有些人在到达HWM时可能会丢弃消息。
发布于 2013-08-14 19:31:56
在没有产生任何错误的情况下,什么才能对未发送的消息负责?
如果您将ROUTER套接字用于从服务器到zmq工作进程的中间消息,ROUTER默认情况下将删除它们无法传递的任何出站消息。“不能送货”是什么意思?路由器维护客户端标识到客户端连接的内部映射,并且由于路由器上的所有消息都具有由客户端提供或由路由器自动分配的标识,任何没有相应连接的出站消息都将被静默地丢弃。
您可以通过告诉路由器报告不可交付的消息来识别此场景何时发生,换句话说,当路由器无法传递消息时,它会生成一个错误。在Java中,方法是routerSocket.setRouterMandatory(true),您只需要找到与此对应的python (我不是py家伙,lol)
如果您确定路由器正在丢弃消息,那么问题就变成了为什么?在我的例子中,我有一个zmq客户端,它在不同的线程上发送和接收服务器消息,而接收线程的连接速度不足以满足来自服务器的初始"Ok“响应,所以这只是客户机中的一个计时问题。
希望这有帮助
发布于 2015-01-03 11:05:38
如果两个系统保证始终处于活动状态(24X7),或者只有在两个系统处于活动状态时才应该发送消息,那么ZeroMQ可以作为一种很好的方式在系统之间传输小事件作为一种很好的选择。
由于订户速度慢,我们在ZeroMQ发布子模式下发送大量消息时遇到了问题,我们开始在中间丢失消息。后来,我们转向了ActiveMQ嵌入式代理模式,它将消息保存在内存中,直到使用者使用它们为止。ZeroMQ的好处是,即使没有发布服务器,也可以启动订阅服务器,或者发行者是否会稍后出现在图片中。
对活动MQ的限制,无法在生产者创建队列之前启动从队列中的使用者读取。它显然会抛出异常。我们也可以使用这两个库,并从每个库中获得最佳效果。
https://stackoverflow.com/questions/18236368
复制相似问题