SpringBoot+RabbitMQ 死信隊(duì)列
點(diǎn)擊上方“碼農(nóng)突圍”,馬上關(guān)注 這里是碼農(nóng)充電第一站,回復(fù)“666”,獲取一份專(zhuān)屬大禮包 真愛(ài),請(qǐng)?jiān)O(shè)置“星標(biāo)”或點(diǎn)個(gè)“在看
前言
dead-letter-exchange)。死信的幾種來(lái)源:
消息 TTL 過(guò)期(time to live,存活時(shí)間,可以用在限時(shí)支付消息) 隊(duì)列達(dá)到最大長(zhǎng)度(隊(duì)列滿了,無(wú)法路由到該隊(duì)列) 消息被拒絕( basic.reject / basic.nack),并且requeue = false

環(huán)境準(zhǔn)備配置
正常交換機(jī) 正常隊(duì)列(最長(zhǎng)隊(duì)列 5) ---- 正常消費(fèi)者,拒絕消息 ttl 隊(duì)列(過(guò)期時(shí)間 60 秒) ---- 沒(méi)有消費(fèi)者 死信交換機(jī) 死信隊(duì)列
@Configuration
public?class?DeadConfig?{
????/*?正常配置?**********************************************************************************************************/
????/**
?????*?正常交換機(jī),開(kāi)啟持久化
?????*/
????@Bean
????DirectExchange?normalExchange()?{
????????return?new?DirectExchange("normalExchange",?true,?false);
????}
????@Bean
????public?Queue?normalQueue()?{
????????// durable:?是否持久化,默認(rèn)是false,持久化隊(duì)列:會(huì)被存儲(chǔ)在磁盤(pán)上,當(dāng)消息代理重啟時(shí)仍然存在,暫存隊(duì)列:當(dāng)前連接有效
????????// exclusive:?默認(rèn)也是false,只能被當(dāng)前創(chuàng)建的連接使用,而且當(dāng)連接關(guān)閉后隊(duì)列即被刪除。此參考優(yōu)先級(jí)高于durable
????????// autoDelete:?是否自動(dòng)刪除,當(dāng)沒(méi)有生產(chǎn)者或者消費(fèi)者使用此隊(duì)列,該隊(duì)列會(huì)自動(dòng)刪除。
????????Map?args?=?deadQueueArgs();
????????//?隊(duì)列設(shè)置最大長(zhǎng)度
????????args.put("x-max-length",?5);
????????return?new?Queue("normalQueue",?true,?false,?false,?args);
????}
????@Bean
????public?Queue?ttlQueue()?{
????????Map?args?=?deadQueueArgs();
????????//?隊(duì)列設(shè)置消息過(guò)期時(shí)間?60?秒
????????args.put("x-message-ttl",?60?*?1000);
????????return?new?Queue("ttlQueue",?true,?false,?false,?args);
????}
????@Bean
????Binding?normalRouteBinding()?{
????????return?BindingBuilder.bind(normalQueue()).to(normalExchange()).with("normalRouting");
????}
????@Bean
????Binding?ttlRouteBinding()?{
????????return?BindingBuilder.bind(ttlQueue()).to(normalExchange()).with("ttlRouting");
????}
????/*?死信配置?**********************************************************************************************************/
????/**
?????*?死信交換機(jī)
?????*/
????@Bean
????DirectExchange?deadExchange()?{
????????return?new?DirectExchange("deadExchange",?true,?false);
????}
????/**
?????*?死信隊(duì)列
?????*/
????@Bean
????public?Queue?deadQueue()?{
????????return?new?Queue("deadQueue",?true,?false,?false);
????}
????@Bean
????Binding?deadRouteBinding()?{
????????return?BindingBuilder.bind(deadQueue()).to(deadExchange()).with("deadRouting");
????}
????/**
?????*?轉(zhuǎn)發(fā)到?死信隊(duì)列,配置參數(shù)
?????*/
????private?Map?deadQueueArgs()? {
????????Map?map?=?new?HashMap<>();
????????//?綁定該隊(duì)列到私信交換機(jī)
????????map.put("x-dead-letter-exchange",?"deadExchange");
????????map.put("x-dead-letter-routing-key",?"deadRouting");
????????return?map;
????}
}

隊(duì)列達(dá)到最大長(zhǎng)度
?/**
??*?正常消息隊(duì)列,隊(duì)列最大長(zhǎng)度5
??*/
?@GetMapping("/normalQueue")
?public?String?normalQueue()?{
?????Map?map?=?new?HashMap<>();
?????map.put("messageId",?String.valueOf(UUID.randomUUID()));
?????map.put("data",?System.currentTimeMillis()?+?",?正常隊(duì)列消息,最大長(zhǎng)度?5");
?????rabbitTemplate.convertAndSend("normalExchange",?"normalRouting",?map,?new?CorrelationData());
?????return?JSONObject.toJSONString(map);
?}

消息 TTL 過(guò)期
消息的TTL :對(duì)于設(shè)置了過(guò)期時(shí)間屬性(expiration)的消息,消息如果在過(guò)期時(shí)間內(nèi)沒(méi)被消費(fèi),會(huì)過(guò)期 隊(duì)列的TTL :對(duì)于設(shè)置了過(guò)期時(shí)間屬性(x-message-ttl)的隊(duì)列,所有路由到這個(gè)隊(duì)列的消息,都會(huì)設(shè)置上這個(gè)過(guò)期時(shí)間
?/**
??*?消息?TTL,?time?to?live
??*/
?@GetMapping("/ttlToDead")
?public?String?ttlToDead()?{
?????Map?map?=?new?HashMap<>();
?????map.put("messageId",?String.valueOf(UUID.randomUUID()));
?????map.put("data",?System.currentTimeMillis()?+?",?ttl隊(duì)列消息");
?????rabbitTemplate.convertAndSend("normalExchange",?"ttlRouting",?map,?new?CorrelationData());
?????return?JSONObject.toJSONString(map);
?}


拒絕消息
@Component
@RabbitListener(queues?=?"normalQueue")
public?class?NormalConsumer?{
????@RabbitHandler
????public?void?process(Map?message,?Channel?channel,?Message?mqMsg) ?throws?IOException?{
????????System.out.println("收到消息,并拒絕重新入隊(duì)?:?"?+?message.toString());
????????channel.basicReject(mqMsg.getMessageProperties().getDeliveryTag(),?false);
????}
}

@Component
@RabbitListener(queues?=?"deadQueue")
public?class?DeadConsumer?{
????@RabbitHandler
????public?void?process(Map?message,?Channel?channel,?Message?mqMsg) ?throws?IOException?{
????????System.out.println("死信隊(duì)列收到消息?:?"?+?message.toString());
????????channel.basicAck(mqMsg.getMessageProperties().getDeliveryTag(),?false);
????}
}
死信隊(duì)列收到消息?:?{data=1631534291765,?正常隊(duì)列消息,最大長(zhǎng)度?5,?messageId=bce3888b-da38-4299-ac88-d22cbe164739}
死信隊(duì)列收到消息?:?{data=1631535222745,?ttl隊(duì)列消息,?messageId=a4617445-5aab-4fac-aec7-5709ea699598}
死信隊(duì)列收到消息?:?{data=1631534503765,?正常隊(duì)列消息,最大長(zhǎng)度?5,?messageId=b65ecaab-5ce7-4597-a32c-c90b67ec46da}
死信隊(duì)列收到消息?:?{data=1631534511468,?正常隊(duì)列消息,最大長(zhǎng)度?5,?messageId=d63d2a4c-e7d3-4f00-a6ca-78e2d62d1d92}
死信隊(duì)列收到消息?:?{data=1631534585087,?正常隊(duì)列消息,最大長(zhǎng)度?5,?messageId=eed0c349-415b-43dc-aa79-c683122a1289}
死信隊(duì)列收到消息?:?{data=1631534588311,?正常隊(duì)列消息,最大長(zhǎng)度?5,?messageId=7a7bd152-f2fa-4a74-b9e6-943ac7cbb3d4}
死信隊(duì)列收到消息?:?{data=1631534608504,?正常隊(duì)列消息,最大長(zhǎng)度?5,?messageId=9de512a1-4ca4-4060-9096-27aba01c1687}
來(lái)源:https://blog.csdn.net/m0_46144826
(完)
碼農(nóng)突圍資料鏈接
1、臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開(kāi)放下載!
2、計(jì)算機(jī)基礎(chǔ)知識(shí)總結(jié)與操作系統(tǒng) PDF 下載
3、艾瑪,終于來(lái)了!《LeetCode Java版題解》.PDF
4、Github 10K+,《LeetCode刷題C/C++版答案》出爐.PDF歡迎添加魚(yú)哥個(gè)人微信:smartfish2020,進(jìn)粉絲群或圍觀朋友圈
評(píng)論
圖片
表情

