情景:
我们正在评估ZeroMQ
(特别是jeroMq
)的事件驱动机制。
应用程序分布在多个服务(发布者和订阅者都是服务)可以存在于同一个jvm或不同节点中,这取决于部署体系结构。
观察
为了玩游戏,我创建了一个 pub
/ sub
模式,其中inproc:
作为传输,使用了jero mq(版本:0.3.5)
问题
使用 inproc:
以及 pub
/ sub
是否可行?
尝试使用Google搜索,但找不到具体的任何见解?
pub
/ sub
的代码示例inproc:
使用jero mq(版本:0.3.5)的inproc pub sub的工作代码示例对以后访问此帖子的人有用。一位发布商发布主题 A
和 B
,两位订阅者分别收到A
和B
/**
* @param args
*/
public static void main(String[] args) {
// The single ZMQ instance
final Context context = ZMQ.context(1);
ExecutorService executorService = Executors.newFixedThreadPool(3);
//Publisher
executorService.execute(new Runnable() {
@Override
public void run() {
startPublishing(context);
}
});
//Subscriber for topic "A"
executorService.execute(new Runnable() {
@Override
public void run() {
startFirstSubscriber(context);
}
});
// Subscriber for topic "B"
executorService.execute(new Runnable() {
@Override
public void run() {
startSecondSubscriber(context);
}
});
}
/**
* Prepare the publisher and publish
*
* @param context
*/
private static void startPublishing(Context context) {
Socket publisher = context.socket(ZMQ.PUB);
publisher.bind("inproc://test");
while (!Thread.currentThread().isInterrupted()) {
// Write two messages, each with an envelope and content
try {
publisher.sendMore("A");
publisher.send("We don't want to see this");
LockSupport.parkNanos(1000);
publisher.sendMore("B");
publisher.send("We would like to see this");
} catch (Throwable e) {
e.printStackTrace();
}
}
publisher.close();
context.term();
}
/**
* Prepare and receive through the subscriber
*
* @param context
*/
private static void startFirstSubscriber(Context context) {
Socket subscriber = context.socket(ZMQ.SUB);
subscriber.connect("inproc://test");
subscriber.subscribe("B".getBytes());
while (!Thread.currentThread().isInterrupted()) {
// Read envelope with address
String address = subscriber.recvStr();
// Read message contents
String contents = subscriber.recvStr();
System.out.println("Subscriber1 " + address + " : " + contents);
}
subscriber.close();
context.term();
}
/**
* Prepare and receive though the subscriber
*
* @param context
*/
private static void startSecondSubscriber(Context context) {
// Prepare our context and subscriber
Socket subscriber = context.socket(ZMQ.SUB);
subscriber.connect("inproc://test");
subscriber.subscribe("A".getBytes());
while (!Thread.currentThread().isInterrupted()) {
// Read envelope with address
String address = subscriber.recvStr();
// Read message contents
String contents = subscriber.recvStr();
System.out.println("Subscriber2 " + address + " : " + contents);
}
subscriber.close();
context.term();
}
答案 0 :(得分:5)
The ZMQ inproc
transport旨在用于不同线程之间的单个进程。当你说“可以存在于同一个jvm 或不同的节点”时(强调我的)我认为你的意思是你将多个进程作为分布式服务而不是单个进程中的多个线程
如果是这种情况,那么不,您尝试做的事情将无法与inproc
一起使用。 PUB-SUB/inproc
可以在多个线程之间的单个进程中正常工作。
编辑以解决评论中的其他问题:
使用inproc
或ipc
之类的传输的原因是因为当您在正确的上下文中使用它时,它比tcp传输更有效(更快)。你可以想象使用混合的传输,但你总是必须绑定并连接在同一个传输上才能使它工作。
这意味着每个节点最多需要三个PUB
或SUB
个套接字 - 一个tcp
发布商可与远程主机上的节点通信,ipc
发布商可以通话到同一主机上不同进程上的节点,以及inproc
发布者与同一进程中不同线程中的节点进行通信。
实际上,在大多数情况下,您只需使用tcp
传输,并且只为一切启动一个套接字 - tcp
无处不在。如果每个套接字负责特定的种信息,那么可以有意义地启动多个套接字。
如果有一个原因是你总是将一种消息类型发送到其他线程并且将一种不同的消息类型发送给其他主机,那么多个套接字是有意义的,但从你的情况来看,从一个节点的角度来看,所有其他节点都是相同的。在那种情况下,我会在任何地方使用tcp
并完成它。