springboot activemq 2 持久化消息 与 持久化订阅

本文介绍如何在Spring Boot应用中优化JMS消息队列,包括减少session重复创建、实现订阅持久化及增加队列订阅者等关键配置。通过具体的代码示例展示如何提升性能并确保消息可靠传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接着上一节http://blog.youkuaiyun.com/cons_step_by_step/article/details/78300427

改动1.减少springboot重复创建session的问题
jmsTemplate的地方加入了CachingConnectionFactory,这样配置可以

    @Bean(name = "myJmsTemplate")
    public JmsTemplate getJmsTemplate(ActiveMQConnectionFactory nonXaJmsConnectionFactory, MessageConverter jacksonJmsMessageConverter){
        //使用CachingConnectionFactory可以提高部分性能。
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setSessionCacheSize(100);
        cachingConnectionFactory.setTargetConnectionFactory(nonXaJmsConnectionFactory);
        JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory);
        //设置deliveryMode(持久化), priority, timeToLive必须开启
        jmsTemplate.setExplicitQosEnabled(true);
        // 设置消息是否持久化
        jmsTemplate.setDeliveryPersistent(true);
        // 设置消息转换器
        jmsTemplate.setMessageConverter(jacksonJmsMessageConverter);
        // 设置消息是否以事务
        jmsTemplate.setSessionTransacted(true);
        return jmsTemplate;
    }

改动2 : 加入订阅持久化
什么是订阅持久化?简单讲就是MQ记住了给每个订阅者发送到了哪里,如果中途发生故障又恢复后,可以从记忆的位置继续发送给订阅者。默认是非持久化订阅,即:订阅者在宕机重启之后,队列中有消息,订阅者也是收不到任何消息的,即便这些消息已经持久化在日志文件或者数据库中。
将原来默认的消息监听容器替换为如下两个配置Bean。这是两个分别的监听Bean,并且他们开启了持久化订阅参数setSubscriptionDurable( true ) ,并且拥有各自的ID,factory.setClientId(“10001”); factory.setClientId(“10002”);具体为什么要这么设置可以参看这篇博文https://www.tuicool.com/articles/UfimyuR

    @Bean(name = "topicContainerFactory1")
    public DefaultJmsListenerContainerFactory topicClient1(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer){
        DefaultJmsListenerContainerFactory factory = defaultJmsListenerContainerFactoryTopic(connectionFactory,configurer);
        factory.setClientId("10001");
        return factory;
    }

    @Bean(name = "topicContainerFactory2")
    public DefaultJmsListenerContainerFactory topicClient2(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer){
        DefaultJmsListenerContainerFactory factory = defaultJmsListenerContainerFactoryTopic(connectionFactory,configurer);
        factory.setClientId("10002");
        return factory;
    }

    /**
     *
     * @param connectionFactory
     * @param configurer
     * @return
     */

    public DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactoryTopic(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        configurer.configure(factory,connectionFactory);
        factory.setPubSubDomain(true);
        factory.setSessionTransacted(true);
        factory.setAutoStartup(true);
        //开启持久化订阅
        factory.setSubscriptionDurable(true);
        return factory;
    }

改动3:对同一个队列的消息多添加了一个订阅者。
MQ可以在订阅者第一次订阅的时候记忆每个订阅者的发送位置,之后进行分别的推送。

@JmsListener(destination = MQ_TOPIC_NAME,containerFactory = "topicContainerFactory1") // 监听指定消息主题
public void receiveMessage1(Message message) throws Exception {
    log.debug("[接收队列1] [收到消息] {}",message);
}

@JmsListener(destination = MQ_TOPIC_NAME,containerFactory = "topicContainerFactory2") // 监听指定消息主题
public void receiveMessage1(Message message) throws Exception {
    log.debug("[接收队列2] [收到消息] {}",message);
}

测试结果:

1>同时开启发布者和两个订阅者,发布者向MQ推送消息。订阅者接收。

2017-10-23 01:09:33.258 DEBUG 14436 --- [enerContainer-1] c.thinvent.service.MessageHandleService  : [接收队列1] [收到消息] Message
2017-10-23 01:09:33.258 DEBUG 14436 --- [enerContainer-1] c.t.service.MessageHandleService2        : [接收队列2] [收到消息] Message
2017-10-23 01:09:33.354 DEBUG 14436 --- [enerContainer-1] c.t.service.MessageHandleService2        : [接收队列2] [收到消息] Message
2017-10-23 01:09:33.354 DEBUG 14436 --- [enerContainer-1] c.thinvent.service.MessageHandleService  : [接收队列1] [收到消息] Message
2017-10-23 01:09:33.407 DEBUG 14436 --- [enerContainer-1] c.t.service.MessageHandleService2        : [接收队列2] [收到消息] Message
2017-10-23 01:09:33.461 DEBUG 14436 --- [enerContainer-1] c.thinvent.service.MessageHandleService  : [接收队列1] [收到消息] Message

2>之后关闭消费者。发布者再发布3条消息。

3>此时可以将MQ服务关闭,模拟宕机。然后启动MQ服务,启动一个订阅者,紧接着会受到后续未发送的3条消息,然后再启动另外的订阅者,紧接着也会受到后续的三条消息。

MQ后续问题: MQ的集群,连接管理。后续用到的时候可以继续学习。集群基础学习地址。http://www.imooc.com/video/15223

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值