Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with Inverted PUB/SUB with ZeroMQ

I'm trying to set up "inverted" PUB/SUB with ZeroMQ.

Meaning that subscribing (SUB) sockets belong to several long-living servers, doing zmq_bind(); and publishing (PUB) socket is a short-lived client and does zmq_connect().

I use a single ipc:// socket.

I expect that a message from the publisher will reach each of subscribers.

The problem: Only one of subscriber processes ever receives messages. If that process dies, publisher gets stuck in zmq_term().

Is this mode of operations supported by zmq? If yes, then what am I doing wrong? If no, then how to implement what I need?

Minimal example with some additional details (in Lua, but this should not matter): https://gist.github.com/938429

like image 441
Alexander Gladysh Avatar asked Apr 23 '11 07:04

Alexander Gladysh


People also ask

How does ZeroMQ work?

ZeroMQ supports common messaging patterns (pub/sub, request/reply, client/server and others) over a variety of transports (TCP, in-process, inter-process, multicast, WebSocket and more), making inter-process messaging as simple as inter-thread messaging. This keeps your code clear, modular and extremely easy to scale.

What is Zmq pub sub?

Pub/Sub is a pattern where the publisher is not programmed to send a message (payload) to a specific receiver. These messages are sent by publishers to specific channels, and receivers can subscribe to one or more channels to consume those same messages.

Does pub/sub use TCP?

To track subscriptions, Redis uses a global variable pubsub_channels which maps channel names to sets of subscribed client objects. A client object represents a TCP-connected client by tracking that connection's file descriptor.

What is message in pub sub?

Publish/subscribe messaging, or pub/sub messaging, is a form of asynchronous service-to-service communication used in serverless and microservices architectures. In a pub/sub model, any message published to a topic is immediately received by all of the subscribers to the topic.


2 Answers

You can't bind multiple sockets to one ipc:// address (we are talking about Unix Domain Socket here ipc:///tmp/test.ipc == file /tmp/test.ipc).

What you can do is bind each SUB socket to a different ipc:// address and have the publisher connect one PUB socket to each of those addresses. ZeroMQ allows one socket to bind/connect to multiple addresses.

The blocking on zmq_term() is most likely do to lingering close issue (i.e. there is a message that the PUB socket is trying to send). Take a look at the ZMQ_LINGER socket option.

like image 153
Neopallium Avatar answered Oct 03 '22 07:10

Neopallium


There's a 'feature' of the ipc:// transport which is that if two processes bind to the same IPC endpoint, the second one will silently steal the binding from the first one. This 'feature' was made to allow processes to recover easily after a crash.

This is why only one subscriber is getting the messages.

Since you have just one publisher, why not bind the publisher, and connect the subscribers to that? Even if the publisher comes and goes, the subscribers will reconnect automatically.

like image 45
Pieter Hintjens Avatar answered Oct 03 '22 07:10

Pieter Hintjens