Zookeeper的功能以及工作原理

转自:https://www.cnblogs.com/felixzh/p/5869212.html

 

前言

前面有一篇博客讲到了spring boot整合jms的使用http://blog.csdn.net/liuchuanhong1/article/details/54603546

但是最近遇到一个需求,需要同时使用jms的队列和topic,于是就有了下面的测试代码:

消费者代码

@Component // 必须加此注解,该类才会被作为Message Driven POJO使用
public class Consumer {
    @JmsListener(destination = "mytest.queue")
    public void receiveQueue(TextMessage text) throws Exception {
        System.out.println(Thread.currentThread().getName()+":Consumer收到的报文为:"+text.getText());
    }
    
    @JmsListener(destination="mytest.topic")
    public void receiveTopic(TextMessage text) throws JMSException{
        System.out.println(text.getText());
    }
}
生产者代码
@Service("producer")
public class Producer {
    @Autowired
    private JmsMessagingTemplate jmsTemplate;
    
    public void sendMessage(Destination destination, final String message){
        jmsTemplate.convertAndSend(destination, message);
    }
}
测试代码
@RunWith(SpringRunner.class)
@SpringBootTest
@EnableAsync //开启对Async的支持,否则异步任务不启作用
public class SpringbootJmsApplicationTests {
    
    @Autowired
    private Producer producer;
    
    @Test
    public void contextLoads() throws InterruptedException {
        while(true){
            Destination destination = new ActiveMQQueue("mytest.queue");
            Destination topic = new ActiveMQTopic("mytest.topic");
            
            for(int i=0; i<100; i++){
                producer.sendMessage(destination, "myname is chhliu!!!"+i);
                producer.sendMessage(topic, "i'm the king of the world!");
            }
        }
    }
}
测试结果如下:
DefaultMessageListenerContainer-6:Consumer收到的报文为:myname is chhliu!!!0
DefaultMessageListenerContainer-3:Consumer收到的报文为:myname is chhliu!!!1
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!2
DefaultMessageListenerContainer-4:Consumer收到的报文为:myname is chhliu!!!3
DefaultMessageListenerContainer-5:Consumer收到的报文为:myname is chhliu!!!4
DefaultMessageListenerContainer-2:Consumer收到的报文为:myname is chhliu!!!5
DefaultMessageListenerContainer-6:Consumer收到的报文为:myname is chhliu!!!6
DefaultMessageListenerContainer-3:Consumer收到的报文为:myname is chhliu!!!7
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!8
DefaultMessageListenerContainer-4:Consumer收到的报文为:myname is chhliu!!!9
发现一个奇怪的现象,貌似topic没有起效果。于是在配置文件中加了一个配置,配置如下:
spring.jms.pub-sub-domain=true
然后再跑了一遍上面的测试代码,测试结果如下:
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
i'm the king of the world!
这次结果是彻底的反了过来,topic生效了,queue却没起作用了。
to be or not to be that's a question!怎么能让两者同时生效了!至少从前面的两次测试结果可以看出,控制哪个生效,是通过设置pubsubdomain来实现的,于是我们解决方案的出发点也在此。

解决方案如下:

@Configuration
@EnableJms
public class JmsConfig {
    @Bean
    public JmsListenerContainerFactory<?> topicListenerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setPubSubDomain(true);
        factory.setConnectionFactory(connectionFactory);
        return factory;
    }
 
    @Bean
    public JmsListenerContainerFactory<?> queueListenerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setPubSubDomain(false);
        factory.setConnectionFactory(connectionFactory);
        return factory;
    }
}
上面的代码的作用是创建了两个JmsListenerContainerFactory,分别是topicListenerFactory和queueListenerFactory,其中topicListenerFactory创建的时候,将pubSubDomain设置成了true,表示该Listener负责处理Topic;queueListenerFactory创建的时候,将pubSubDomain设置成了false,也就是说,jms默认就是queue模式,该Listener主要负责处理Queue。
修改消费者代码:

@Component // 必须加此注解,该类才会被作为Message Driven POJO使用
public class Consumer {
    @JmsListener(destination = "mytest.queue" ,containerFactory="queueListenerFactory")// 增加对应处理的监听器工程
    public void receiveQueue(TextMessage text) throws Exception {
        System.out.println(Thread.currentThread().getName()+":Consumer收到的报文为:"+text.getText());
    }
    
    @JmsListener(destination="mytest.topic", containerFactory="topicListenerFactory")// 增加对应处理的监听器工程
    public void receiveTopic(TextMessage text) throws JMSException{
        System.out.println(text.getText());
    }
}
再跑一下前面的测试,结果如下:
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!1
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!2
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!3
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!4
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!5
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!6
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!7
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!8
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!9
i'm the king of the world!
DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!10
i'm the king of the world!
我们发现,Queue和Topic都生效了。但是却产生了另外一个问题,并发消费不启作用了,从上面跑的测试结果可以看出,消费线程都是DefaultMessageListenerContainer-1这个线程,那怎么来解决这个问题了,突破口在DefaultJmsListenerContainerFactory上,该类有很多的配置,我们可以根据项目的需求来添加配置,例如,如果想并发消费生效,可以加如下配置

factory.setTaskExecutor(Executors.newFixedThreadPool(6));
        factory.setConcurrency("6");
其他的配置,可以看源码了解。
--------------------- 
作者:牛奋lch 
来源:CSDN 
原文:https://blog.csdn.net/liuchuanhong1/article/details/72726337 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值