ActiveMQ中的topic消息如何实现负载均衡?

       我们都知道topic消息是给所有的接收者都会发送一份消息的,但是当消息的数量超过一定数据后,单一的一个消费者是会出现消费瓶颈的,在jms2.0中提供了createSharedConsumer共享消费者的方式来实现负载均衡,降低单个消费者出现的瓶颈,但是在目前的activemq中只实现了jms1.1的支持,那么我们该怎么实现消费者的负载均衡呢?

       在activemq中提出了一个virtualTopic的方式来实现负载均衡,我们都知道queue中的消息只能发送给一个消费者进行消费,因此在activemq中就借用了这种思想,它通过将发送给virtualTopic中的消息转发给queue然后实现负载均衡

      官方文档路径是 https://activemq.apache.org/virtual-destinations,我们首先看下在activemq服务器的配置如下

<destinationInterceptors>
	<virtualDestinationInterceptor>
		<virtualDestinations>
		<!--
			name:主题名,可以是通配符
			prefix:队列的前缀
			selectorAware:表示从Topic中将消息转发给Queue时,是否关注Consumer的
			selector情况。如果为false,那么Topic中的消息全部转发给Queue,否则只会转发匹配Queue
			Consumer的selector的消息
		-->
			<virtualTopic name="virtualTopic.>" prefix="virtualTopicConsumers.*." selectorAware="false"/>
		</virtualDestinations>
	</virtualDestinationInterceptor>
</destinationInterceptors>

       通配符说明:https://activemq.apache.org/wildcards     

        ActiveMQ 的queue和topic名称支持通配符,通过通配符可以增强queue和topic的功能
         . 用于分隔path名称
          * 用于匹配任何path名称
          > 用于递归匹配以xx名称开头的任何目标
       示例:
           com.study.*.mq 匹配com.study.a.mq,不匹配com.study.a.b.mq
           com.> com.study.a.mq和com.study.a.b.mq都匹配
       通配符可用于生产和消费者,在生产者中使用通配符时,消息将发送到所有匹配的目标上;在消费者中使用通配符时,将接收所有匹配的目标的消息。       

我们实现的代码是结合了springboot来实现的,直接引入spring-boot-starter-activemq即可,生产端代码如下

/**
     * 负载均衡测试
     * @return
     */
    @GetMapping("/testVirtualTopicMQ")
    public BaseResponse testVirtualTopicMQ(){
        BaseResponse baseResponse = new BaseResponse();
        baseResponse.setCode(ResponseCode.SUCCESS);
        baseResponse.setMsg("测试virtualTopic");
        try {
            OrderDeleteDTO orderDeleteDTO = new OrderDeleteDTO();
            orderDeleteDTO.setOrderId("5");
            orderDeleteDTO.setUserType("01");

            for (int i = 0;i < 10;i++){
                topicJmsTemplate.convertAndSend("virtualTopic.topic", orderDeleteDTO,message -> {
                    message.setStringProperty("name","virtualTopic");
                    return message;
                });
                /*topicJmsTemplate.execute((session, producer) -> {
                    Message message = topicJmsTemplate.getMessageConverter().toMessage(orderDeleteDTO, session);
                    // 添加property属性,因为header为固定的
                    message.setStringProperty("name","virtualTopic");
                    Destination destination = session.createTopic("virtualTopic.topic");
                    producer.send(destination,message);
                    return null;
                });*/
            }
        } catch (Exception e) {
            log.error("测试virtualTopic错误:{}", e);
            baseResponse.setCode(ResponseCode.SERVER_ERROR);
            baseResponse.setMsg("服务器错误");
        }
        return baseResponse;
    }

       消费端的代码如下:

@JmsListener(destination = "virtualTopicConsumers.virtualTopic1.virtualTopic.topic")
    public void testVirtualTopicMQ1(OrderDeleteDTO orderDeleteDTO,
                                    @Header(value = "name") String name) {
        System.out.println("testVirtualTopicMQ1:" + orderDeleteDTO + ":" + name);
    }

    @JmsListener(destination = "virtualTopicConsumers.virtualTopic1.virtualTopic.topic")
    public void testVirtualTopicMQ1_1(OrderDeleteDTO orderDeleteDTO,
                                    @Header(value = "name") String name) {
        System.out.println("testVirtualTopicMQ1_1:" + orderDeleteDTO + ":" + name);
    }

    @JmsListener(destination = "virtualTopicConsumers.virtualTopic2.virtualTopic.topic")
    public void testVirtualTopicMQ2(OrderDeleteDTO orderDeleteDTO,
                                    @Header(value = "name") String name) {
        System.out.println("testVirtualTopicMQ2:" + orderDeleteDTO + ":" + name);
    }

    @JmsListener(destination = "virtualTopicConsumers.virtualTopic2.virtualTopic.topic")
    public void testVirtualTopicMQ2_1(OrderDeleteDTO orderDeleteDTO,
                                    @Header(value = "name") String name) {
        System.out.println("testVirtualTopicMQ2_1:" + orderDeleteDTO + ":" + name);
    }

       在这里一定要注意的是activemq的配置文件prefix的配置以及消费者的订阅路径,不然很容易出错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值