Missing Message Problem Solver
下面是这张图表的总结:
在SUB套接字上,使用ZMQ_SUBSCRIBE的zmq_setsockopt()设置订阅,否则将得不到消息。因为您通过前缀订阅消息,如果您订阅“”(空订阅),您将获得所有内容。
如果您在PUB套接字开始发送数据之后启动SUB套接字(即,建立到PUB套接字的连接),您将丢失它在建立连接之前发布的所有数据。如果这是一个问题,请设置您的体系结构,使SUB套接字首先启动,然后PUB套接字开始发布。
即使同步了SUB和PUB套接字,仍然可能会丢失消息。这是因为在实际创建连接之前,不会创建内部队列。如果你可以切换绑定/连接方向,让SUB套接字绑定,PUB套接字连接,你可能会发现它的工作方式更像你期望的。
如果您正在使用REP和REQ套接字,并且没有坚持同步send/recv/send/recv命令,ZeroMQ将报告错误,您可能会忽略这些错误。那样的话,就会显得你在丢失信息。如果您使用REQ或REP,请坚持send/recv顺序,并且始终在实际代码中检查ZeroMQ调用的错误。
如果您正在使用PUSH套接字,您将发现第一个要连接的PULL套接字将获取不公平的消息共享。消息的准确旋转只发生在所有PULL套接字都成功连接时,这可能需要一些毫秒。作为PUSH/PULL的替代方案,为了降低数据速率,可以考虑使用ROUTER/DEALER和负载平衡模式。
如果您正在跨线程共享套接字,请不要这样做。它会导致随机的奇怪,和崩溃。
如果您正在使用inproc,请确保两个套接字处于相同的上下文中。否则,连接端实际上会失效。同样,先绑定,再连接。Inproc不是像tcp那样的断开连接的传输。
如果您正在使用ROUTER套接字,那么通过发送错误的标识帧(或忘记发送标识帧),很容易意外地丢失消息。一般来说,在ROUTER套接字上设置ZMQ_ROUTER_MANDATORY选项是个好主意,但在每次发送调用时也要检查返回代码。
最后,如果您真的不能找出问题出在哪里,那么就做一个重现问题的最小测试用例,并向ZeroMQ社区寻求帮助。