死信隊列
當消息處理消費失敗後,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