ActiveMq虚拟主题+SpringBoot

本文介绍了ActiveMQ中的虚拟主题(Virtual Topic)功能,用于解决订阅者负载均衡和故障转移问题。虚拟主题允许消息发布者使用`VirtualTopic.`开头的Topic,并在消费者端通过不同的队列前缀实现分组消费。示例展示了如何创建和监听虚拟主题,以及如何自定义消费虚拟地址。此外,还提供了SpringBoot框架下监听虚拟主题的配置方法。
摘要由CSDN通过智能技术生成

【前情回顾】:最近在做项目的过程中,需要用到虚拟主题。本文以Activemq为主。一般情况下主题的使用都是订阅一个mq的name,然后对这个name进行监听,做业务逻辑处理。但是之前从没听过虚拟主题,后来一番了解之后,特地总结一下。

【简介】:

ActiveMQ中,topic只有在持久订阅下才是持久化的。持久订阅时,每个持久订阅者,都相当于一个queue的客户端,它会收取所有消息。这种情况下存在两个问题: 
1:同一应用内consumer端负载均衡的问题:也即是同一个应用上的一个持久订阅不能使用多个consumer来共同承担消息处理功能。因为每个consumer都会获取所有消息。 
queue模式可以解决这个问题,但broker端又不能将消息发送到多个应用端。所以,既要发布订阅,又要让消费者分组,这个功能JMS规范本身是没有的。 
2:同一应用内consumer端failover的问题:由于只能使用单个的持久订阅者,如果这个订阅者出错,则应用就无法处理消息了,系统的健壮性不高 

为了解决这两个问题,ActiveMQ中实现了虚拟Topic的功能。

【虚拟主题的使用】:

1.创建

对于消息发布者来说,正常的Topic,名称以VirtualTopic.开头。比如现有一个虚拟的topic的name为:VirtualTopic.myTopic。使用的时候命名为:Consumer.XXX.VirtualTopic.myTopic。

public class VirtualTopic {
    public void createVirtualTopic () {
        ConnectionFactory connectionFactory = new
                ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        Connection connection = connectionFactory.createConnection();
        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        Destination destination = session.createTopic("VirtualTopic.myTopic");
        MessageProducer producer = session.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);//设置传送模式为持久模式,默认为非持久
        connection.start();
        for(int i=0; i<3; i++) {
            TextMessage message = session.createTextMessage("message--"+i);
            Thread.sleep(1000);
            //通过消息生产者发出消息
            producer.send(message);
        }
        session.commit();
        session.close();
        connection.close();
    }
}

2.监听

对于消息接收端来说,是个队列,不同应用里使用不同的前缀作为队列的名称,即可表明自己的身份即可实现消费端应用分组。本文重在对虚拟主题的使用,结合SpringBoot框架。具体步骤如下:

  1. 编写配置文件。
  2. 创建queue。
  3. 监听对应的queue。
@Configuration
public class ListenerContainerConfig {
    //对应application.properties中activemq的url
    @Value("${spring.activemq.broker-url}")
    private String url;
    //对应application.properties中activemq的user
    @Value("${spring.activemq.user}")
    private String username;
    //对应application.properties中activemq的password
    @Value("${spring.activemq.password}")
    private String password;

    @Bean("queueListenerContainer")
    public JmsListenerContainerFactory queueListenerContainer() {
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
        //监听的是Queue
        bean.setPubSubDomain(false);
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(username, password, url);
        bean.setConnectionFactory(connectionFactory);
        return bean;
    }
}

 创建一个name为:Consumer.A.VirtualTopic.myTopic

//在初始化的时候创建queue
@Bean
    public void createVirtualTopic(){
        logger.info("虚拟主题初始化...");
        new ActiveMQQueue("Consumer.A.VirtualTopic.myTopic");
    }

 监听对应的queue:

@JmsListener(destination = "Consumer.A.VirtualTopic.myTopic", containerFactory = "queueListenerContainer")
    public void subscribeHeatMatchEvent(String content) {
        //接收报文,对事件进行JSON字符串解析。
        //进行业务逻辑操作
        
    }

【扩展】:自定义更改消费虚拟地址

默认虚拟主题的前缀是 :VirtualTopic.*。自定义消费虚拟地址默认格式:Consumer.*.VirtualTopic.*。
自定义消费虚拟地址可以改,比如下面的配置就把它修改了。
xml配置示例如下:
<broker xmlns="http://activemq.apache.org/schema/core">
    <destinationInterceptors>
        <virtualDestinationInterceptor>
            <virtualDestinations>
                <virtualTopic name=">" prefix="VirtualTopicConsumers.*." selectorAware="false"/><!-- 修改的Consumer的开头格式-->
            </virtualDestinations>
        </virtualDestinationInterceptor>
    </destinationInterceptors>
</broker>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值