ActiveMQ案例——Topic主题(发布订阅模式)

public class TopicPersistentTest {
    //编写消息的发送端-----生产者
    @Test
    public void test1() throws Exception{
        //创建链接工厂对象
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        //从工厂中获取一个链接对象
        Connection connection = connectionFactory.createConnection();
        //获取session对象
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //通过session对象创建主题
        Topic topic = session.createTopic("topic");
        //通过session对象创建消息的发送者
        MessageProducer producer = session.createProducer(topic);
        //开启持久化
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);

        //连接MQ服务
        connection.start();

        //通过session创建消息对象
        TextMessage message = session.createTextMessage("ping");
        //发送消息
        producer.send(message, DeliveryMode.PERSISTENT, 1, 1000*60*60*24);
        //关闭相关资源
        producer.close();
        session.close();
        connection.close();
    }

    //编写消息的接收端-----消费者
    @Test
    public void test2() throws Exception{
        //创建链接工厂对象
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        //从工厂中获取一个链接对象
        Connection connection = connectionFactory.createConnection();
        //设置客户端id
        connection.setClientID("client-1");
        //连接MQ服务
        connection.start();
        //获取session对象
        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //通过session对象创建主题
        Topic topic = session.createTopic("topic");
        //通过session对象创建消息的消费者
//        MessageConsumer consumer = session.createConsumer(topic);
        //设置主体的订阅者
        TopicSubscriber consumer = session.createDurableSubscriber(topic, "client1-sub");
        //指定消息监听器1
        consumer.setMessageListener(new MessageListener() {
            //当监听的topic中存在消息,这个方法自动执行
            public void onMessage(Message message) {
                if (null != message && message instanceof TextMessage){
                    TextMessage textMessage = (TextMessage) message;
                    try {
                        System.out.println("消费者接收到了消息:" + textMessage.getText());
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        while(true) {

        }
    }
}

总结:

  1. 在使用Topic主题处理消息时,消费者必须先订阅主题,消费者不能接收到主题订阅之前产生的消息
  2. 在获取Session对象时如果事务设置为true,则需要调用commit方法提交事务
  3. 在获取Session对象时如果开启手动签收,必须调用acknowledge方法手动签收,否则消息不会被消费
  4. 如果开启事务,则会强制自动签收,即当事务被成功提交则消息被自动签收,如果事务回滚,则消息会被再次传送。创建Session对象的第二个签收参数无效
  5. 生产者开启持久化后,服务器宕机后重启服务器,消费者也能接收到宕机前发送的消息,关闭持久化之后则不能接收到宕机前的消息。默认开启了持久化
  6. 非持久订阅只有当消费者与MQ保持连接状态才能接收到发送到某个主题的消息,如果消费者处于离线状态,生产者发送的主题消息将会丢失,消费者不会接收到
  7. 持久订阅:客户端首先向MQ注册一个自己的身份ID识别号,当这个客户端处于离线时,生成者会为这个ID保存所有发送到主题的消息,当消费者再次连接到MQ时会根据消费者的ID得到所有当自己处于离线状态时发送到主题的消息
  8. 非持久订阅状态下,不能恢复或重新派送一个未签收的消息
  9. 持久订阅状态下才能恢复或重新派送一个未签收的消息
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章