Is it normal?
such question is so easy to be asked, but so hard to get answered with no other details and contexts available.
ZeroMQ
"Missing Message Problem" chapter in the great Pieter HINTJENS' book "Code Connected Volume 1"
says a few general principles on this subject:
• On SUB
sockets, set a subscription using zmq_setsockopt()
with ZMQ_SUBSCRIBE
, or you won’t get messages. Because you subscribe to messages by prefix, if you subscribe to ""
(an empty subscription), you will get everything.
• If you start the SUB
socket (i.e., establish a connection to a PUB
socket) after the PUB
socket has started sending out data, you will lose whatever it published before the connection was made. If this is a problem, set up your architecture so the SUB
socket starts first, then the PUB
socket starts publishing.
• Even if you synchronize a SUB
and PUB
socket, you may still lose messages. It’s due to the fact that internal queues aren’t created until a connection is actually created. If you can switch the bind
/connect
direction so the SUB
socket bind
-s, and the PUB
socket connect
-s, you may find it works more as you’d expect.
• If you’re using REP
and REQ
sockets, and you’re not sticking to the synchronous send
/recv
/send
/recv
order, ØMQ will report errors, which you might ignore. Then, it would look like you’re losing messages. If you use REQ
or REP
, stick to the send
/recv
order, and always, in real code, check for errors on ØMQ calls.
• If you’re using PUSH
sockets, you’ll find that the first PULL
socket to connect will grab an unfair share of messages. The accurate rotation of messages only happens when all PULL
sockets are successfully connected, which can take some milliseconds. As an alternative to PUSH
/PULL
, for lower data rates, consider using ROUTER
/DEALER
and the load balancing pattern.
• If you’re sharing sockets across threads, don’t. It will lead to random weirdness, and crashes.
• If you’re using inproc
, make sure both sockets are in the same context
. Otherwise the connecting side will in fact fail. Also, bind
first, then connect
. inproc
is not a disconnected transport like tcp
.
• If you’re using ROUTER
sockets, it’s remarkably easy to lose messages by accident, by sending malformed identity frames (or forgetting to send
an identity frame). In general setting the ZMQ_ROUTER_MANDATORY
option on ROUTER
sockets is a good idea, but do also check the return code on every send
call.
• Lastly, if you really can’t figure out what’s going wrong, make a minimal test case that reproduces the problem, and ask for help from the ØMQ community.