死信队列
当消息处理消费失败后,Spring Cloud Stream 会自动默认重试3次,重试三次失败后,RepublishMessageRecoverer类recover方法会将改变routingkey为队列名称发送至死信队列。目前产生死信队列有两种方式:
- 默认自动为每个消息队列产生一个死信队列,消费失败时会路由至该队列的死信队列
- 直接指定每个消息队列绑定的死信队列,多个消息队列可绑定同一个死信队列
本项目采用第2种方式,便于所有消费失败信息处理
大致流程
涉及事件系统重试参考其他文章
配置步骤
注意若系统中已经存在的消息队列,一定要在rabbitmq删除该队列,否则无法创建死信队列。 只需要配置spring.cloud.rabbit.bindings部分 其中有两个注意点:
- spring.cloud.bindings.input.group和spring.cloud.bindings.input.destination必须要配置,并且值不能一致,否则因为springcloud Dalston.SR1版本问题,死信消息队列的routing Key会取数错误,详细可参见RabbitMessageChannelBinder类createConsumerEndpoint方法,Spring Cloud 2.0发现该代码已经大部分改动了,没有BUG。
- maxAttempts 可根据实际情况判断是否需要重试
spring:
cloud:
stream:
bindings:
input:
group: cms-infra-group #需要保证与destination 不一样,否则死信队列路由标准代码有BUG
destination: cms-infra #发送消息的exchange名称,自动生成,如果不给值将为binding名称,比如input
springCloudBusInput:
group: cms-infra
default:
consumer:
maxAttempts: 1 #默认为3次,禁用重试
rabbit:
bindings:
input:
consumer:
autoBindDlq: true #启用死信队列,默认会生成一个DLX EXCHANGE,当消息重复消费失败后
#死信队列配置,可不给值
#dlqTtl: 5000 #死信队列 消息存放时间 ,最好不要设置不然消息将会丢弃
dlqDeadLetterExchange: XXX.DLX #如果该列声明,那么deadLetterExchange也要声明,这个保持一致
deadLetterExchange: XXX.DLX #与dlqDeadLetterExchange保持一致
deadLetterQueueName: XXX.dlq #死信队列名称,可不给值,默认prefix+destination.dlq
#死信队列配置,可不给值
republishToDlq: true #该值为false如果设置了死信队列,消息对原封不动的发送到死信队列,如果为true,则消息对带上错误信息发送至死信队列
requeueRejected: true #默认false,只能抛AmqpRejectAndDontRequeueException消息才能到死信队列,如果为true,所有错误消息都会抛到死信队列
#prefix: feign-test2 #声明exchange、queue前缀
#bindingRoutingKey: feign-test.destination 默认为#,如果是动态binding模式,producer发送的routingKey 默认为destination