ZeroMQ,我们可以使用inproc:transport以及pub / sub消息传递模式

时间:2016-02-17 10:18:46

标签: java zeromq publish-subscribe event-driven-design jeromq

情景:

我们正在评估ZeroMQ(特别是jeroMq)的事件驱动机制。

应用程序分布在多个服务(发布者和订阅者都是服务)可以存在于同一个jvm或不同节点中,这取决于部署体系结构。

观察

为了玩游戏,我创建了一个 pub / sub模式,其中inproc:作为传输,使用了jero mq(版本:0.3.5)

  1. 线程发布能够发布(看起来像发布,至少没有错误)
  2. 另一个帖子中的订阅者没有收到任何内容。
  3. 问题

    使用 inproc: 以及 pub / sub 是否可行?

    尝试使用Google搜索,但找不到具体的任何见解?

    pub / sub的代码示例inproc:

    使用jero mq(版本:0.3.5)的inproc pub sub的工作代码示例对以后访问此帖子的人有用。一位发布商发布主题 A B ,两位订阅者分别收到AB

    /**
     * @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();
    
    }
    

1 个答案:

答案 0 :(得分:5)

The ZMQ inproc transport旨在用于不同线程之间的单个进程。当你说“可以存在于同一个jvm 或不同的节点”时(强调我的)我认为你的意思是你将多个进程作为分布式服务而不是单个进程中的多个线程

如果是这种情况,那么不,您尝试做的事情将无法与inproc一起使用。 PUB-SUB/inproc可以在多个线程之间的单个进程中正常工作。

编辑以解决评论中的其他问题:

使用inprocipc之类的传输的原因是因为当您在正确的上下文中使用它时,它比tcp传输更有效(更快)。你可以想象使用混合的传输,但你总是必须绑定并连接在同一个传输上才能使它工作。

这意味着每个节点最多需要三个PUBSUB个套接字 - 一个tcp发布商可与远程主机上的节点通信,ipc发布商可以通话到同一主机上不同进程上的节点,以及inproc发布者与同一进程中不同线程中的节点进行通信。

实际上,在大多数情况下,您只需使用tcp传输,并且只为一切启动一个套接字 - tcp无处不在。如果每个套接字负责特定的信息,那么可以有意义地启动多个套接字。

如果有一个原因是你总是将一种消息类型发送到其他线程并且将一种不同的消息类型发送给其他主机,那么多个套接字是有意义的,但从你的情况来看,从一个节点的角度来看,所有其他节点都是相同的。在那种情况下,我会在任何地方使用tcp并完成它。