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

时间:2015-09-09 05:42:12

标签: jms activemq

我遇到了JMS Connection 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();
        }
    }
}

}

我的想法是模拟连接stop()和start()。因此,在调用stop()之后的消费者线程中,我已经安排了5秒的睡眠。但是,同时生产者线程继续将消息发送到队列。

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

我在这里做错了吗?

1 个答案:

答案 0 :(得分:0)

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

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

希望这会有所帮助。