springboot activemq关闭持久化不起作用

该博客介绍了如何使用JmsTemplate配置ActiveMQ连接,并启用deliveryMode、priority和timeToLive的显式QoS设置。通过设置`setExplicitQosEnabled(true)`确保这些参数生效。同时,设置了消息为非持久化,不开启事务,并指定消费者需手动acknowledge签收消息。

需要写jmsTemplate.setExplicitQosEnabled(true);

    @Bean
    public JmsTemplate jmsTemplate(ActiveMQConnectionFactory connectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory(connectionFactory);
        //deliveryMode, priority, timeToLive 的开关,要生效,必须配置为true,默认false
        jmsTemplate.setExplicitQosEnabled(true);
        // 持久化消息
        jmsTemplate.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        // 是否开启事务
        jmsTemplate.setSessionTransacted(false);
        // 消费者receive消息后必须手动的调用acknowledge()方法进行签收
        jmsTemplate.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
        return jmsTemplate;
    }
<think>我们正在处理一个关于在Spring Boot中配置ActiveMQ持久订阅的问题。根据提供的引用,我们可以总结出以下关键点: 1. **引用[1]**:配置文件中需要设置`spring.jms.pub-sub-domain=true`来启用发布/订阅模式(默认为点对点模式)。 2. **引用[2]**:展示了如何编写一个监听器来订阅主题(Topic)消息。使用`@JmsListener`注解,并指定要监听的目的地(主题名称)。 3. **引用[3]**:Maven依赖配置,包括`spring-boot-starter-activemq`和`activemq-pool`(连接池)。 4. **引用[4]**:发布消息的示例代码,其中通过设置`jmsTemplate.setPubSubDomain(true)`来指定使用发布/订阅模式(主题)。 5. **引用[5]**:配置持久化订阅的关键点,包括使用`CachingConnectionFactory`来缓存会话(Session)以提高性能,以及设置消息持久化(`setDeliveryPersistent(true)`)和事务(`setSessionTransacted(true)`)。 **持久订阅(Durable Subscription)** 是发布/订阅模型中的一个重要概念。它允许消费者在离线时也能接收到消息。当消费者重新连接时,会接收到离线期间发送到主题的消息。要实现持久订阅,需要: - 消费者在订阅时指定一个唯一的客户端ID(Client ID)和订阅者名称(Subscription Name)。 - 消费者需要保持相同的客户端ID和订阅者名称来重新连接,以便恢复会话。 ### 配置步骤 根据以上引用,我们可以整理出在Spring Boot中配置ActiveMQ持久订阅的步骤: #### 1. 添加依赖 在`pom.xml`中添加ActiveMQ和连接池依赖(如引用[3]所示): ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> <version>5.15.0</version> <!-- 版本根据实际情况调整 --> </dependency> ``` #### 2. 配置文件 在`application.properties`(或`application.yml`)中配置ActiveMQ连接和发布/订阅模式(引用[1]): ```properties # ActiveMQ配置 spring.activemq.broker-url=tcp://127.0.0.1:61616 spring.activemq.user=admin spring.activemq.password=admin # 启用发布/订阅模式(主题) spring.jms.pub-sub-domain=true # 设置客户端ID,用于持久订阅(每个订阅者需要唯一的client-id) spring.activemq.client-id=myClientId ``` 注意:持久订阅要求每个订阅者都有一个唯一的客户端ID。因此,我们配置了`spring.activemq.client-id`属性。但是,如果应用有多个实例,需要确保每个实例的客户端ID不同(例如,通过程序设置)。 #### 3. 配置JmsTemplate(可选,用于发送消息) 如果需要发送消息,可以配置一个JmsTemplate,如引用[4]和[5]所示。但通常Spring Boot会自动配置JmsTemplate,我们只需要在需要发布消息的地方注入即可。为了确保发布的消息是持久的,需要设置消息的传递模式为持久化(DeliveryMode.PERSISTENT)。默认情况下,JmsTemplate发送的消息是持久的,但我们可以显式设置(引用[5]中设置了`jmsTemplate.setDeliveryPersistent(true)`)。 #### 4. 配置持久订阅的监听器 创建监听器类,使用`@JmsListener`注解来订阅主题,并指定`subscription`属性(用于持久订阅的订阅者名称)和`clientId`(如果未在配置文件中设置全局客户端ID,也可以在此指定)。但是,在Spring Boot中,我们通常在配置文件中设置客户端ID,然后在监听器中使用`subscription`属性。 示例(参考引用[2]并修改为持久订阅): ```java @Component public class SpringBootActiveMqCustomerTopic { @JmsListener(destination = "${bootqueueinfo}", containerFactory = "jmsListenerContainerFactory", subscription = "myDurableSubscription") // 订阅者名称 public void receive(TextMessage textMessage) throws Exception { // 处理消息 } } ``` 注意:为了支持持久订阅,我们需要配置一个特定的`JmsListenerContainerFactory`,因为默认的工厂可能没有设置必要的属性(如客户端ID和持久订阅)。 #### 5. 配置JmsListenerContainerFactory 在Spring Boot中,我们可以自定义一个`JmsListenerContainerFactory`来支持持久订阅。例如: ```java @Configuration @EnableJms public class ActiveMQConfig { @Value("${spring.activemq.client-id}") private String clientId; @Bean public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); // 设置为发布/订阅模式(主题) factory.setPubSubDomain(true); // 设置客户端ID(用于持久订阅) factory.setClientId(clientId); // 开启持久订阅 factory.setSubscriptionDurable(true); // 其他配置,如并发数等 return factory; } } ``` 这样,当我们在监听器中使用`containerFactory = "jmsListenerContainerFactory"`时,就会使用这个配置的工厂来创建监听容器,并支持持久订阅。 ### 注意事项 - 持久订阅要求客户端ID唯一,且订阅者名称(subscription name)在同一个客户端ID下唯一。 - 如果应用有多个实例,每个实例必须有不同的客户端ID,否则它们会相互覆盖。通常,我们可以为每个实例生成唯一的客户端ID(例如,使用UUID)。 - 持久订阅的消息会被ActiveMQ存储,直到所有活跃的持久订阅者都消费了该消息,或者消息过期。 ### 总结步骤 1. 添加依赖。 2. 配置`application.properties`,设置ActiveMQ连接信息、客户端ID和启用发布/订阅模式。 3. 自定义`JmsListenerContainerFactory`,设置客户端ID、启用发布/订阅模式和持久订阅。 4. 在监听器方法上使用`@JmsListener`,指定`destination`、`containerFactory`和`subscription`(订阅者名称)。 这样,我们就配置了一个持久订阅的消费者。 ### 相关问题 根据用户的问题,我们生成以下相关问题: 1. 在Spring Boot中如何为ActiveMQ的多个实例配置不同的客户端ID? 2. 如何验证ActiveMQ的持久订阅是否生效? 3. 持久订阅的消息存储机制是什么?消息何时会被删除? 4. 如何配置ActiveMQ的消息持久化存储方式(如KahaDB、JDBC等)?</think>### Spring Boot 配置 ActiveMQ 持久订阅 在 Spring Boot 中配置 ActiveMQ 持久订阅需要以下关键步骤,确保离线时消息不丢失: #### 1. 添加依赖(pom.xml) ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> <version>5.15.0</version> </dependency> ``` *引用依赖配置[^3]* #### 2. 配置文件(application.properties) ```properties # 启用发布/订阅模式 spring.jms.pub-sub-domain=true # 设置客户端ID(持久订阅必需) spring.activemq.client-id=client-001 # ActiveMQ 连接配置 spring.activemq.broker-url=tcp://127.0.0.1:61616 spring.activemq.user=admin spring.activemq.password=admin ``` *关键配置:`client-id` 标识持久订阅者,`pub-sub-domain=true` 启用主题模式[^1]* #### 3. 配置 JmsTemplate持久化发送) ```java @Bean public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) { JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory); jmsTemplate.setPubSubDomain(true); // 启用发布/订阅 jmsTemplate.setDeliveryPersistent(true); // 消息持久化 return jmsTemplate; } ``` *设置 `setDeliveryPersistent(true)` 保证消息持久化存储[^5]* #### 4. 实现持久订阅监听器 ```java @Component public class DurableSubscriber { // 注册持久订阅监听器 @JmsListener( destination = "myTopic", subscription = "myDurableSub", // 订阅唯一标识 containerFactory = "jmsListenerContainerFactory" ) public void receive(String message) { System.out.println("收到持久消息: " + message); } } ``` *关键参数:`subscription` 定义唯一订阅名[^2]* #### 5. 配置监听容器工厂 ```java @Bean public DefaultJmsListenerContainerFactory jmsListenerContainerFactory( ConnectionFactory connectionFactory) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setPubSubDomain(true); // 主题模式 factory.setSubscriptionDurable(true); // 启用持久订阅 factory.setClientId("client-001"); // 匹配配置文件中的client-id return factory; } ``` *必须设置 `setSubscriptionDurable(true)` 和匹配的 `clientId`[^5]* #### 验证步骤: 1. **启动应用**:首次启动自动注册持久订阅 2. **停止消费者**:通过管理后台发送测试消息 3. **重启消费者**:应收到离线期间发送的消息 4. **ActiveMQ 控制台**:查看订阅者列表显示 `Durable` 标识 > **注意**:同一个 `client-id + subscription` 组合只能有一个活跃消费者,否则会导致消息分发冲突。 ### 持久订阅工作原理 $$ \text{持久订阅} = \text{ClientID} + \text{SubscriptionName} + \text{持久化存储} $$ 当消费者离线时,ActiveMQ 会将消息存储在订阅者的专属空间中,并在重新连接后按顺序投递[^2]。 ### 常见问题解决 - **消息未持久化**:检查 `setDeliveryPersistent(true)` 和 broker 存储配置 - **重复消费**:确保不同实例使用不同的 `client-id` - **订阅不生效**:确认 `spring.jms.pub-sub-domain=true` 已配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值