本篇內(nèi)容介紹了“RabbitMQ是怎么確定消息是否投遞到隊列中的”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
公司主營業(yè)務(wù):網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)建站是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)建站推出丘北免費做網(wǎng)站回饋大家。
1. 前言
在使用RabbitMQ消息中間件時,因為消息的投遞是異步的,默認(rèn)情況下,RabbitMQ會刪除那些無法路由的消息。為了能夠檢出消息是否順利投遞到隊列,我們需要相應(yīng)的處理機制。今天就來驗證一下相關(guān)的驗證機制。
2. 消息投遞失敗
那么哪些情況消息會投遞失敗呢?RabbitMQ消息會先到達(dá)指定的交換機,然后由交換機路由到對應(yīng)的隊列。所以以下幾種情況會導(dǎo)致消息投遞失敗。
投遞的交換機不可用。
投遞的交換機可用,但是沒有匹配到隊列。
3. 投遞失敗的處理機制
對應(yīng)上面的兩種情況,RabbitMQ提供了對應(yīng)的解決方案。
ConfirmCallback
RabbitMQ提供了ConfirmCallback接口用于實現(xiàn)消息發(fā)送到RabbitMQ交換器后進(jìn)行確認(rèn)回調(diào)。
在Spring Boot中需要開啟:
spring: rabbitmq: # 通常選擇 correlated publisher-confirm-type:
通常有三種選擇:
NONE ,禁用發(fā)布確認(rèn)模式,是默認(rèn)值。
CORRELATED,發(fā)布消息時會攜帶一個CorrelationData,被ack/nack時CorrelationData會被返回進(jìn)行對照處理,CorrelationData可以包含比較豐富的元信息進(jìn)行回調(diào)邏輯的處理。
SIMPLE,當(dāng)被ack/nack后會等待所有消息被發(fā)布,如果超時會觸發(fā)異常,甚至關(guān)閉連接通道。
這里我使用CORRELATED模式,聲明一個ConfirmCallback并設(shè)置到RabbitTemplate中
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> { // correlationData 可能為空 if (ack) { log.debug("消息發(fā)送到exchange成功,id: {}", correlationData.getId()); } else { log.debug("消息發(fā)送到exchange失敗,原因: {}", cause); } });
當(dāng)消息投遞到一個不存在的交換機Exchange且ack=false時會輸出日志:
- Publishing message [(Body:'"hello"' MessageProperties [headers={spring_listener_return_correlation=a088eb3f-a234-4e15-bb7a-3aa9a6f043e6, spring_returned_message_correlation=29975bc1-f363-4e3a-85ca-010d13888720, __TypeId__=java.lang.String}, contentType=application/json, contentEncoding=UTF-8, contentLength=7, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])] on exchange [DIRECT_EXCHANGE1], routingKey = [DIRECT_ROUTING_KEY2] - 消息發(fā)送到exchange失敗,原因: channel error; protocol method: #method(reply-code=404, reply-text=NOT_FOUND - no exchange 'DIRECT_EXCHANGE1' in vhost 'my_vhost', class-id=60, method-id=40)
這里實現(xiàn)的比較簡單你可以增加一些消息投遞到交換機失敗后的操作處理邏輯。
ReturnCallback
ReturnCallback接口用于實現(xiàn)消息已經(jīng)成功發(fā)送到RabbitMQ交換機,但沒有匹配到隊列時的回調(diào)。
在Spring Boot中需要同時開啟:
spring: rabbitmq: publisher-returns: true template: mandatory: true
RabbitTemplate中的mandatory設(shè)置值優(yōu)先級要高一些。
我們聲明一個ReturnCallback并設(shè)置到RabbitTemplate中
rabbitTemplate.setMandatory(true); rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> { String correlationId = message.getMessageProperties() .getHeader(PublisherCallbackChannel.RETURNED_MESSAGE_CORRELATION_KEY); log.debug("消息:{} 發(fā)送失敗, 應(yīng)答碼:{} 原因:{} 交換機: {} 路由鍵: {}", correlationId, replyCode, replyText, exchange, routingKey); });
當(dāng)消息成功投遞到交換機但是無法匹配到隊列時:
- Publishing message [(Body:'"hello"' MessageProperties [headers={spring_listener_return_correlation=155648bd-fc3e-4c8b-a650-7b1ce720c7a6, spring_returned_message_correlation=7029ee49-357a-42fc-8532-dc41b4bb8e87, __TypeId__=java.lang.String}, contentType=application/json, contentEncoding=UTF-8, contentLength=7, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])] on exchange [DIRECT_EXCHANGE], routingKey = [DIRECT_ROUTING_KEY2] - 消息:7029ee49-357a-42fc-8532-dc41b4bb8e87 發(fā)送失敗, 應(yīng)答碼:312 原因:NO_ROUTE 交換機: DIRECT_EXCHANGE 路由鍵: DIRECT_ROUTING_KEY2 - 消息發(fā)送到exchange成功,id: 7029ee49-357a-42fc-8532-dc41b4bb8e87
從上面我們也可以看出ReturnCallback只處理投遞到隊列失敗的情況,并不像ConfirmCallback既能處理失敗的情況也能處理成功的情況。
“RabbitMQ是怎么確定消息是否投遞到隊列中的”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!