需求与思路:
避免消费端消费消息失败之后重试再消费失败再重试的死循环,将重试计数放入Redis中,超过指定次数后消息进入死信队列。同时关于手动确认这段代码使用AOP做统一处理。
据查阅资料:
开启手动确认后spring的消息重试就不起作用了,加入请求头中计数经我测试也不起作用(或许是我姿势有问题,网上有人介绍这种方法,反正我没成功)故此我选择Redis作为消息重试计数
首先创建队列与交换机,这里采用配置文件方式,不采用注解方式(微服务项目统一管理)
import com.fanlyun.rabbitmq.core.constants.AmqpConstant;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RabbitmqConfig {
// 声明业务Exchange
@Bean("networkLetterExchange")
public TopicExchange networkLetterExchange(){
return new TopicExchange(AmqpConstant.NETWORK_LETTER_EXCHANGE);
}
// 声明死信Exchange
@Bean("deadLetterExchange")
public DirectExchange deadLetterExchange(){
return new DirectExchange(AmqpConstant.DEAD_LETTER_EXCHANGE);
}
// 声明网络运单队列
@Bean("networkQueueReceive")
public Queue networkQueueReceive(){
Map<String, Object> args = new HashMap<>(2);
// x-dead-letter-exchange 这里声明当前队列绑定的死信交换机
args.put("x-dead-letter-exchange",AmqpConstant.DEAD_LETTER_EXCHANGE);
// x-dead-letter-routing-key 这里声明当前队列的死信路由key
args.put("x-dead-letter-routing-key", AmqpConstant.DEAD_LETTER_QUEUE_ROUTING_KEY);
// args.put("x-message-ttl",10000);//设置队列消息的超时时间,单位毫秒,超过时间进入死信队列
// args.put("x-max-length", 10);//生命队列的最大长度,超过长度的消息进入死信队列
return QueueBuilder.durable(AmqpConstant.NETWORK_LETTER_QUEUE_RECEIVE).withArguments(args).build();
}
// 声明网络运单队列
@Bean("networkQueueTest")
public Queue networkQueueTest(){
Map<String, Object> args = new HashMap<>(2);
// x-dead-letter-exchange 这里声明当前队列绑定的死信交换机
args.put("x-dead-letter-exchange",AmqpConstant.DEAD_LETTER_EXCHANGE);
// x-dead-letter-routing-key 这里声明当前队列的死信路由key
args.put("x-dead-letter-routing-key", AmqpConstant.DEAD_LETTER_QUEUE_ROUTING_KEY);
// args.put("x-message-ttl",10000);//设置队列消息的超时时间,单位毫秒,超过时间进入死信队列
// args.put("x-max-length", 10);//生命队列的最大长度,超过长度的消息进入死信队列
return QueueBuilder.durable(AmqpConstant.NETWORK_LETTER_QUEUE_TEST).withArguments(args).build();
}
// 声明死信队列
@Bean("deadLetterQueue")
public Queue deadLetterQueue(){
return new Queue(AmqpConstant.DEAD_LETTER_QUEUE_NAME);
}
/*
将网络运单队列绑定网络运单交换机 接收网络运单
*/
@Bean
public Binding bindingExchangeNetworkReceive(@Qualifier("networkQueueReceive") Queue queue,@Qualifier("networkLetterExchange") TopicExchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(AmqpConstant.NETWORK_LETTER_ROUTING_RECEIVE);
}
/*
将网络运单队列绑定网络运单交换机 测试网络运单
*/
@Bean
public Binding

该博客提出避免消费端消息消费失败死循环的方案,将重试计数放入Redis,超指定次数消息进死信队列,用AOP统一处理手动确认代码。介绍了创建队列与交换机、发送消息类、自定义注解等内容,还给出超过三次进入死信队列的代码及yml配置。

2188

被折叠的 条评论
为什么被折叠?



