接着上一节http://blog.csdn.net/cons_step_by_step/article/details/78300427。 web
改动1.减小springboot重复建立session的问题
jmsTemplate的地方加入了CachingConnectionFactory,这样配置能够spring
@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能够在订阅者第一次订阅的时候记忆每一个订阅者的发送位置,以后进行分别的推送。springboot
@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); }
测试结果:session
1>同时开启发布者和两个订阅者,发布者向MQ推送消息。订阅者接收。ide
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条消息。svg
3>此时能够将MQ服务关闭,模拟宕机。而后启动MQ服务,启动一个订阅者,紧接着会受到后续未发送的3条消息,而后再启动另外的订阅者,紧接着也会受到后续的三条消息。性能
MQ后续问题: MQ的集群,链接管理。后续用到的时候能够继续学习。集群基础学习地址。http://www.imooc.com/video/15223 学习