ZMQ Pub Sub - 它应该丢弃消息吗?

时间:2014-09-17 18:30:39

标签: java publish zeromq subscribe

试图测试pub / sub的简单实现。我发现,如果我将订阅者留下并发送消息,则订阅者不会全部收到订阅者。有时候所有人都收到了,有时候是部分的,有时甚至不会收到整套。

运行订阅服务器(保持运行状态),然后多次运行发布服务器。

import org.zeromq.ZMQ;
import org.zeromq.ZMQ.Context;
import org.zeromq.ZMQ.Socket;


public static void main (String[] args) {

    // Prepare our context and subscriber
    Context context = ZMQ.context(1);
    Socket subscriber = context.socket(ZMQ.SUB);

    subscriber.connect("tcp://localhost:5563");
    subscriber.subscribe("B".getBytes());


    System.out.println("Starting Subscriber..");
    int i = 0;
    while (true) {
        String address = subscriber.recvStr();
        String contents = subscriber.recvStr();
        System.out.println(address+":"+new String(contents) + ": "+(i));
        i++;
    }

}

}

出版商:

import org.zeromq.ZMQ;
import org.zeromq.ZMQ.Context;
import org.zeromq.ZMQ.Socket;


public class TestPublisher {

public static void main (String[] args) throws Exception {
    Context context = ZMQ.context(1);
    Socket publisher = context.socket(ZMQ.PUB);
    publisher.bind("tcp://*:5563");
    System.out.println("Starting Publisher..");
    publisher.setIdentity("B".getBytes());
    publisher.setHWM(1000);
    for (int i = 0; i < 10; i++) {
        Thread.sleep(10l);
        publisher.sendMore("B");
        boolean isSent = publisher.send("We would like to see this:"+i);
        System.out.println("Message was sent "+i+" , "+isSent);
    }

    Thread.sleep(1000);
    publisher.close ();
    context.term ();
}

}

2 个答案:

答案 0 :(得分:2)

经过一些调试后发现问题是,在发布套接字绑定时花了一点时间并试图发布刚丢弃的消息。在初始绑定上添加100ms的简单睡眠修复此问题。在prod环境中,发布者已经在启动时受到约束。

猜猜这是一个单线解决方案。现在,具有平均数据量的pub / sub的所有消息都可以正常工作而不会丢失任何数据。请参阅下面的发布商的代码段更新。

import org.zeromq.ZMQ;
import org.zeromq.ZMQ.Context;
import org.zeromq.ZMQ.Socket;


public class TestPublisher {

    public static void main (String[] args) throws Exception {
        Context context = ZMQ.context(1);
        Socket publisher = context.socket(ZMQ.PUB);

        publisher.bind("tcp://*:5563");
        System.out.println("Starting Publisher..");
        publisher.setIdentity("B".getBytes());
        // for testing setting sleep at 100ms to ensure started.
        Thread.sleep(100l);
        for (int i = 1; i <= 10; i++) {
            publisher.sendMore("B");
            boolean isSent = publisher.send("X("+System.currentTimeMillis()+"):"+i);
            System.out.println("Message was sent "+i+" , "+isSent);
        }

        publisher.close ();
        context.term ();
    }
}

答案 1 :(得分:0)

zmq guide的第5章“高级发布 - 子模式”涵盖了可靠的发布/订阅。但是,如果您的服务器始终在生产中运行,那么除了您已经投入的睡眠以使测试正常工作之外,您不需要做任何其他事情。

如果您真的想解决订阅者消息的问题,第5章中的“获取带外快照”示例将涵盖它。