springboot整合activemq重试机制问题
mq的配置类
当mq的工厂类没有配置重试机制时,默认使用自带的
package com.huayunworld.electricity.config.activemq;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.RedeliveryPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import javax.annotation.Resource;
/**
* activemq配置
*
* @author zhangxu
* @date 2019/12/20 10:43
*/
@Configuration
@Slf4j
public class ActivemqConfig {
@Resource
private ActivemqProperties activemqProperties;
/**
* 监听mq的广播模式
*/
public static final String TOPIC = "topicModel";
/**
* 监听mq的队列模式
*/
public static final String QUEUE = "queueModel";
@Bean
public MessageConverter messageConverter() {
return new MappingJackson2MessageConverter();
}
@Bean
public DefaultMessageHandlerMethodFactory handlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(messageConverter());
return factory;
}
/**
* 支持topic模式
*
* @param connectionFactory
* @return
*/
@Bean(name = TOPIC)
public JmsListenerContainerFactory<?> topic(ActiveMQConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
// topic 模式
factory.setPubSubDomain(true);
//设置持久化
factory.setSubscriptionDurable(true);
factory.setClientId("njdlClient01");
factory.setSessionTransacted(true);
factory.setAutoStartup(true);
return factory;
}
/**
* 支持queue模式
*
* @param connectionFactory
* @return
*/
@Bean(name = QUEUE)
public JmsListenerContainerFactory<?> queue(ActiveMQConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
/**
* 配置mq重试机制
*
* @return
*/
@Bean
public RedeliveryPolicy redeliveryPolicy() {
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
// 是否在每次尝试重新发送失败后,增长这个等待时间
redeliveryPolicy.setUseExponentialBackOff(true);
// 重发次数,默认为6次
redeliveryPolicy.setMaximumRedeliveries(activemqProperties.getMaximumRedeliveries());
// 重发时间间隔,单位毫秒 默认为1秒
redeliveryPolicy.setInitialRedeliveryDelay(activemqProperties.getInitialRedeliveryDelay());
// 第一次失败后重新发送之前等待1秒, 第二次 1*5
redeliveryPolicy.setBackOffMultiplier(activemqProperties.getBackOffMultiplier());
// 是否避免消息碰撞
redeliveryPolicy.setUseCollisionAvoidance(false);
// 设置重发最大拖延时间-1 表示没有拖延只有UseExponentialBackOff(true)为true时生效
redeliveryPolicy.setMaximumRedeliveryDelay(-1);
return redeliveryPolicy;
}
/**
* 连接工厂配置
*
* @param url activemq地址
* @param username 用户名
* @param password 密码
* @return
*/
@Bean
public ActiveMQConnectionFactory activeMqConnectionFactory(@Value("${spring.activemq.broker-url}") String url,
@Value("${spring.activemq.user}") String username,
@Value("${spring.activemq.password}") String password) {
ActiveMQConnectionFactory activeMqConnectionFactory = new ActiveMQConnectionFactory(username, password, url);
return activeMqConnectionFactory;
}
}
消费者代码
如果里面不使用try{}catch{}的时候:当消费失败后,重启服务会重试消费默认6次
如果使用了try{}catch{}的时候,当消费失败后,不会重试消费
import com.alibaba.fastjson.JSONArray;
import com.huayunworld.electricity.config.activemq.ActivemqConfig;
import com.huayunworld.electricity.config.interceptor.MyBatisInterceptor;
import com.huayunworld.electricity.constant.EntConst;
import com.huayunworld.electricity.constant.QueueName;
import com.huayunworld.electricity.dao.mysql.TapeOperTicketItemDao;
import com.huayunworld.electricity.model.db.TapeOperTicketItem;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author lilonglong
* @Description 执行录音通知
* @date 2022/2/17 11:19
*/
@Slf4j
@Component
public class ExecTapeListener {
@Autowired
private TapeOperTicketItemDao tapeOperTicketItemDao;
/**
* @return void
* @Description 缓存录音数据到持久层
* @Date 11:20 2022/2/17
* @Param [java.lang.String]
**/
@JmsListener(destination = QueueName.NOTICE_ORDER_TAPE_EXEC, containerFactory = ActivemqConfig.QUEUE)
public void listener(String data) {
log.debug("录音数据:{}", data);
List<TapeOperTicketItem> tapeOperTicketItems = JSONArray.parseArray(data, TapeOperTicketItem.class);
if (CollectionUtils.isEmpty(tapeOperTicketItems)) {
log.debug("没有录音数据!!!");
return;
}
int i = 0;
try {
MyBatisInterceptor.setEntId(EntConst.JSDL);
//批量插入录音数据
i = tapeOperTicketItemDao.insertBatchTapeOper(tapeOperTicketItems);
} catch (Exception e) {
log.error("保存录音数据异常!", e);
}
log.info("批量插入录音数据结果:{}", i);
}
}