JMS连接在连接停止时传递发送到队列的消息

JMS连接在连接停止时传递发送到队列的消息,jms,activemq,Jms,Activemq,我面临JMS连接stop()和start()的问题。一个简单的java程序说明了这一点: public class Test { static Connection producerConn = null; static BufferedWriter consumerLog = null; static BufferedWriter producerLog = null; public static final void main(String[] args)

我面临JMS连接stop()和start()的问题。一个简单的java程序说明了这一点:

public class Test {
    static Connection producerConn = null;
    static BufferedWriter consumerLog = null;
    static BufferedWriter producerLog = null;

    public static final void main(String[] args) throws Exception {
        ConnectionFactory cf = new ActiveMQConnectionFactory("failover:(tcp://localhost:61616)");
        producerConn = cf.createConnection();

    producerLog = new BufferedWriter(new FileWriter("produced.log"));
    consumerLog = new BufferedWriter(new FileWriter("consumed.log"));

    new Thread(new Runnable() {
        public void run() {
            try {
                producerConn.start();
                Session session = producerConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
                Queue queue = session.createQueue("SampleQ1");
                MessageProducer producer = session.createProducer(queue);
                Random random = new Random();
                byte[] messageBytes = new byte[1024];

                for (int i = 0; i < 100; i++) {
                    random.nextBytes(messageBytes);
                    Message message = session.createObjectMessage(messageBytes);
                    producer.send(message);
                    Thread.currentThread().sleep(10);
                    producerLog.write(message.getJMSMessageID());
                    producerLog.newLine();
                    producerLog.flush();
                }
                System.out.println("Produced 100000 messages...");
                producerLog.close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

    System.out.println("Started producer...");


    new Thread(new Runnable() {
        public void run() {
            int count = 0;
            try {
                producerConn.start();
                Session session = producerConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
                Queue queue = session.createQueue("SampleQ1");
                MessageConsumer consumer = session.createConsumer(queue);
                consumer.setMessageListener(new Test().new MyListener());
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

    System.out.println("Started consumer...");
}

private class MyListener implements MessageListener{
    private int count = 0;

    public void onMessage(Message message) {
        try {
            message.acknowledge();
            System.out.println("count is " +count++);
            if(count == 5){
                producerConn.stop();
                System.out.println("Sleeping Now for 5 seconds. . ." +System.currentTimeMillis());
                Thread.currentThread().sleep(5000);
                producerConn.start();
            }
            System.out.println("Waking up . . ." +System.currentTimeMillis());
            consumerLog.write(message.getJMSMessageID());
            consumerLog.newLine();
            consumerLog.flush();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
公共类测试{
静态连接producerConn=null;
静态BufferedWriter consumerLog=null;
静态缓冲写入程序producerLog=null;
公共静态最终void main(字符串[]args)引发异常{
ConnectionFactory cf=new-ActiveMQConnectionFactory(“故障转移:(tcp://localhost:61616)");
producerConn=cf.createConnection();
producerLog=newbufferedwriter(newfilewriter(“producted.log”);
consumerLog=new BufferedWriter(新文件写入程序(“consumed.log”);
新线程(newrunnable()){
公开募捐{
试一试{
producerConn.start();
Session Session=producerConn.createSession(假,Session.AUTO_确认);
Queue Queue=session.createQueue(“SampleQ1”);
MessageProducer=session.createProducer(队列);
随机=新随机();
字节[]消息字节=新字节[1024];
对于(int i=0;i<100;i++){
random.nextBytes(messageBytes);
Message Message=session.createObjectMessage(messageBytes);
生产者。发送(消息);
Thread.currentThread().sleep(10);
write(message.getJMSMessageID());
producerLog.newLine();
producerLog.flush();
}
System.out.println(“生成100000条消息…”);
producerLog.close();
}
捕获(例外e){
e、 printStackTrace();
}
}
}).start();
System.out.println(“开始制作…”);
新线程(newrunnable()){
公开募捐{
整数计数=0;
试一试{
producerConn.start();
Session Session=producerConn.createSession(假,Session.AUTO_确认);
Queue Queue=session.createQueue(“SampleQ1”);
MessageConsumer=session.createConsumer(队列);
consumer.setMessageListener(new Test().new MyListener());
}
捕获(例外e){
e、 printStackTrace();
}
}
}).start();
System.out.println(“已启动的消费者…”);
}
私有类MyListener实现MessageListener{
私有整数计数=0;
消息(消息消息)上的公共无效{
试一试{
message.acknowledge();
System.out.println(“count是”+count++”);
如果(计数=5){
producerConn.stop();
System.out.println(“现在睡眠5秒…”+System.currentTimeMillis());
Thread.currentThread().sleep(5000);
producerConn.start();
}
System.out.println(“唤醒…”+System.currentTimeMillis());
write(message.getJMSMessageID());
consumerLog.newLine();
consumerLog.flush();
}
捕获(例外e){
e、 printStackTrace();
}
}
}
}

我的想法是模拟连接stop()和start()。因此,在调用stop()后的使用者线程中,我设置了5秒的睡眠时间。然而,与此同时,生产者线程继续其向队列发送消息的工作

我希望测试只使用在消费者调用stop()之前和从睡眠中醒来后再次调用start()之后传递的消息。但这里发生的是,当消费者醒来时,它会读取来自服务器的所有消息,甚至是当消费者的消息接收停止时发送到队列的消息


我在这里做错了什么吗?

那里没有什么错,这是正确的行为。在异步消息传递中,生产者和消费者是松散解耦的。生产者并不关心消费者是否在消费消息。当消费者可能停机、停止消费消息或主动消费消息时,它会不断将消息放入队列

connection.stop()方法对生产者没有影响。它只影响使用者,stop()方法暂停从JMS提供程序向使用者传递消息,而start()方法启动/恢复消息传递


希望这有帮助。

这没有错,这是正确的行为。在异步消息传递中,生产者和消费者是松散解耦的。生产者并不关心消费者是否在消费消息。当消费者可能停机、停止消费消息或主动消费消息时,它会不断将消息放入队列

connection.stop()方法对生产者没有影响。它只影响使用者,stop()方法暂停从JMS提供程序向使用者传递消息,而start()方法启动/恢复消息传递


希望这有帮助。

是的,沙希。这对制片人来说是正确的。它不会阻止制作人生成消息。但我关心的是消费者。使用者不得使用在连接停止时发送到队列的消息。连接停止时发送到队列的消息不应该被丢弃吗?不,JMS提供程序不会丢弃消息,而且这也是不正确的行为。消费者应用程序需要处理丢弃时间戳早于消费者连接的消息。start.Ok。谢谢沙石的回答。但我还有一个问题。当我修改相同的示例以创建Publisher/Subscriber代替Producer/Consumer时,我观察到了相同的行为。我的意思是,即使不创建DurableSubscriber,我也观察到一种类似于DurableSubscriber的行为。我是说我的订户