What I wrote last time Introduction and use of ZeroMQ (1)
Pipeline pattern
PipeLine mode is used for task allocation, usually in multi-level PipeLine, one or several nodes push the work to many workers, and then push the results to one or several collectors in turn. This pattern is reliable in most cases, because it does not drop messages unless the node is unexpectedly disconnected. It is scalable because nodes can join at any time.
ZeroMQ supports PipeLine through two types:
- PUSH type
- PULL type
PUSH socket
PUSH uses a circular algorithm to send messages as a group of anonymous PULL peers. The receive operation does not have this Socket type implementation.
When PUSHSocket enters into mute state because it has reached the high water level of all downstream nodes, or if there is no downstream node at all, any sending operation on the Socket will be blocked until the mute state ends or at least one downstream node can be sent; the message will not be discarded.
Feature summary:
Compatible peer socket | PULL |
direction | one-way |
Send / receive mode | Send only |
Access routing strategy | Not applicable |
Outgoing routing policy | Round robin |
Action in mute state | block |
PULL socket
The PULL type talks to a group of anonymous PUSH peers and receives messages using a fair queuing algorithm.
This socket type is not implemented for this send operation.
Feature summary:
Compatible peer socket | PUSH |
direction | one-way |
Send / receive mode | Receive only |
Access routing strategy | Fair queuing |
Outgoing routing policy | Not applicable |
Action in mute state | block |
Code instance
PUSH:
package ndm2.ndm2; import java.io.IOException; import java.util.Random; import org.zeromq.SocketType; import org.zeromq.ZContext; import org.zeromq.ZMQ; import org.zeromq.ZMQ.Socket; public class ZMQDemoPush { public static void main(String[] args) throws InterruptedException, IOException { ZContext context = new ZContext(); ZMQ.Socket sender = context.createSocket(SocketType.PUSH); sender.bind("tcp://localhost:5557"); for (int i = 0; i < 100; ++i) { sender.send("this is a test", 0); Thread.sleep(1000); // Give 0MQ time to deliver } } }
pull:
package ndm2.ndm2; import java.io.IOException; import java.util.Random; import org.zeromq.SocketType; import org.zeromq.ZContext; import org.zeromq.ZMQ; import org.zeromq.ZMQ.Socket; public class ZMQDemoPull { public static void main(String[] args) throws InterruptedException, IOException { ZContext context = new ZContext(); ZMQ.Socket receiver = context.createSocket(SocketType.PULL); receiver.connect("tcp://localhost:5557"); while (!Thread.currentThread().isInterrupted()) { String string = new String(receiver.recv(0), ZMQ.CHARSET).trim(); System.out.println(string + '.'); } } }
test result
Exclusive pair mode
PAIR
PAIR can only connect to a single peer at a time. Messages sent through PAIR Socket are not routed or filtered.
When PAIR is muted because it has reached the high watermark of the connected peer, or if no peer is connected, any send operation on the Socket will block until the peer is available for sending; the message will not be discarded.
Although PAIR can be used for transport other than inproc, they cannot automatically reconnect and the fact that new incoming connections will be terminated, and any previous connections (including those in the closed state) will not be suitable for TCP in most cases.
Code example
private static class Step1 extends Thread { private ZContext context; private Step1(ZContext context) { this.context = context; } @Override public void run() { Socket xmitter = context.createSocket(SocketType.PAIR); xmitter.connect("inproc://step2"); System.out.println("Step 1 Be ready, transmit step 2"); xmitter.send("I'm number one", 0); xmitter.close(); } } private static class Step2 extends Thread{ private ZContext context; private Step2(ZContext context){ this.context = context; } @Override public void run() { Socket receiver = context.createSocket(SocketType.PAIR); receiver.bind("inproc://step2"); String str = new String(receiver.recv(0)); System.out.println(str); receiver.close(); Socket xmitter = context.createSocket(SocketType.PAIR); xmitter.connect("inproc://step3"); System.out.println("Step 2 Be ready, transmit step 3"); xmitter.send("I'm number two", 0); xmitter.close(); } } private static class Step3 extends Thread { private ZContext context; private Step3(ZContext context) { this.context = context; } @Override public void run() { Socket receiver = context.createSocket(SocketType.PAIR); receiver.bind("inproc://step3"); String str = new String(receiver.recv(0)); System.out.println(str); receiver.close(); System.out.println("Step 3 Be ready"); } } public static void main(String[] args) throws InterruptedException{ ZContext context = new ZContext(); Thread step1 = new Step1(context); step1.start(); Thread step2 = new Step2(context); step2.start(); Thread step3 = new Step3(context); step3.start(); step1.join(); step2.join(); step3.join(); System.out.println("Success!"); }
Since the following modes are not implemented, there is no instance. The following is the general content:
Client server mode
The CLIENT SERVER mode is used to allow a single SERVER server to talk to one or more CLIENT clients. The CLIENT always starts a conversation, after which any peer can send a message asynchronously to the other party.
Client
The CLIENT type talks to one or more SERVER peers. If it is connected to multiple peers, it circulates messages sent between them. When reading, it will read fairly from each of its peers in turn. It is reliable because it does not normally discard messages.
If the CLIENT socket has established a connection, the send operation will accept the message, queue the message, and send the message as soon as the network allows. The output buffer limit is defined by the socket's high watermark. If the outgoing buffer is full or there are no connected peers, the send operation is blocked by default. The CLIENT socket does not drop messages.
Feature summary:
Compatible peer socket | The server |
direction | Bidirectional |
Send / receive mode | Unlimited |
Outgoing routing policy | Round robin |
Access routing strategy | Fair queuing |
Action in mute state | block |
SERVER
The SERVER type talks to zero or more CLIENT peers. Each outgoing message is sent to a specific peer CLIENT. The SERVER socket can only reply to incoming messages: the CLIENT peer must always start a conversation.
Each received message has a routing "ID, which is a 32-bit unsigned integer. To send a message to a given CLIENT peer, the application must set the routing ID of the peer on the message.
If you do not specify the routing_id, or if you do not reference a connected client peer, the send call fails. If the client peer's outgoing buffer is full, the send call is blocked. In no case will the SERVER socket discard messages.
Feature summary:
Compatible peer socket | Customer |
direction | Bidirectional |
Send / receive mode | Unlimited |
Outgoing routing policy | See text |
Access routing strategy | Fair queuing |
Action in mute state | fail |
Radio dish mode
Radio mode is used to fan out data from a single publisher to multiple subscribers.
Radio dish is using a group (relative to the pub sub topic). Dish socket can join a group, and each message sent by radio socket belongs to a group.
A group is a null terminated string limited to 16 characters, including null. The goal is to increase the length to 40 characters, including null. The encoding of the group should be UTF8.
Use exact match (prefix match of vs PubSub) to match groups
Radio
Publishers use RADIO to distribute data. Each message belongs to a group. The message will be distributed to all members of the group. The receive operation is not implemented by this socket type.
When RADIO enters the mute state because it has reached the highest water level of the subscriber, any message that will be sent to the subscriber in question will be discarded until the mute state ends. The send operation will not block this socket type.
Feature summary:
Compatible peer socket | dish |
direction | one-way |
Send / receive mode | Send only |
Access routing strategy | Not applicable |
Outgoing routing policy | Fan out |
Action in mute state | decline |
DISH
Subscribers use DISH to subscribe to RADIO distributed groups. Initially, the DISH socket did not subscribe to any groups. The send operation is not implemented by this socket type.
Feature summary:
Compatible peer socket | radio |
direction | one-way |
Send / receive mode | Receive only |
Access routing strategy | Fair queuing |
Outgoing routing policy | Not applicable |