ActiveMQ案例——Queue队列(点对点模式)

public class QueueTest {
    //编写消息的发送端-----生产者
    @Test
    public void test1() throws Exception{
        //创建链接工厂对象
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        //从工厂中获取一个链接对象
        Connection connection = connectionFactory.createConnection();
         //获取session对象  第一个参数为事务,第二个参数为签收
        //如果事务设置为true,则需要调用commit方法提交事务
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //通过session对象创建目的地(主题/队列)
        Destination destination = session.createQueue("queue");
        //通过session对象创建消息的发送者(生产者)
        MessageProducer producer = session.createProducer(destination);
         //开启持久化
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        //连接MQ服务
        connection.start();
    
        //通过session创建消息对象
        TextMessage message = session.createTextMessage("ping");
        //设置消息属性
        message.setStringProperty("c01", "vip");
        //MapMessage消息对象
        MapMessage mapMessage = session.createMapMessage();
        mapMessage.setString("key", "value");
        //设置消息是否持久化  默认开启了持久化
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

        //发送消息
        producer.send(message);
        producer.send(mapMessage);
        //关闭相关资源
        producer.close();
        session.close();
        connection.close();
    }

    //编写消息的接收端-----消费者
    @Test
    public void test2() throws Exception{
        //创建链接工厂对象
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        //从工厂中获取一个链接对象
        Connection connection = connectionFactory.createConnection();
        //连接MQ服务
        connection.start();
       //获取session对象 开启手动签收后 必须调用acknowledge方法手动签收,否则消息不会被消费
        //如果开启事务,则会强制自动签收
        final Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
        //通过session对象创建目的地(主题/队列)
        Destination destination = session.createQueue("queue");
        //通过session对象创建消息的消费者
        MessageConsumer consumer = session.createConsumer(destination);
        //指定消息监听器
        consumer.setMessageListener(new MessageListener() {
            //当监听的queue中存在消息,这个方法自动执行
            public void onMessage(Message message) {
                if (null != message && message instanceof TextMessage){
                    TextMessage textMessage = (TextMessage) message;
                    try {
                        System.out.println("消费者接收到了textMessage消息:" + textMessage.getText());
                        System.out.println("消费者接收到了消息属性:" + textMessage.getStringProperty("c01"));
                        //客户端手动确认签收
                        message.acknowledge();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (null != message && message instanceof MapMessage){
                    MapMessage mapMessage = (MapMessage) message;
                    try {
                        System.out.println("消费者接收到了mapMessage消息:" + mapMessage.getString("key"));
                        //客户端手动确认
                      message.acknowledge();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        while(true) {

        }
    }
}

总结:

  1. 在使用Queue队列处理消息时,无论消费者在消息产生前和产生后开启,消息都能够接收到,即消费者开启前的消息不会丢失
  2. 在获取Session对象时如果事务设置为true,则需要调用commit方法提交事务
  3. 在获取Session对象时如果开启手动签收,必须调用acknowledge方法手动签收,否则消息不会被消费
  4. 如果开启事务,则会强制自动签收,即当事务被成功提交则消息被自动签收,如果事务回滚,则消息会被再次传送。创建Session对象的第二个签收参数无效
  5. 如果在Session关闭时有消息已被接收到但还没有被签收,那当消费者下次连接到相同的队列时,这些消息还会被再次接受
  6. 生产者开启持久化后,服务器宕机后重启服务器,消费者也能接收到宕机前发送的消息,关闭持久化之后则不能接收到宕机前的消息。默认开启了持久化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章