最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

RabbitMQ死信機(jī)制實(shí)現(xiàn)延遲隊(duì)列的實(shí)戰(zhàn)

 更新時(shí)間:2021年11月11日 11:00:50   作者:wxd_1024  
本文主要介紹了RabbitMQ死信機(jī)制實(shí)現(xiàn)延遲隊(duì)列的實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

延遲隊(duì)列

延遲隊(duì)列存儲(chǔ)的對(duì)象肯定是對(duì)應(yīng)的延時(shí)消息,所謂”延時(shí)消息”是指當(dāng)消息被發(fā)送以后,并不想讓消費(fèi)者立即拿到消息,而是等待指定時(shí)間后,消費(fèi)者才拿到這個(gè)消息進(jìn)行消費(fèi)。

應(yīng)用場(chǎng)景

三方支付,掃碼支付調(diào)用上游的掃碼接口,當(dāng)掃碼有效期過(guò)后去調(diào)用查詢接口查詢結(jié)果。實(shí)現(xiàn)方式:每當(dāng)一筆掃碼支付請(qǐng)求后,立即將此訂單號(hào)放入延遲隊(duì)列中(RabbitMQ),隊(duì)列過(guò)期時(shí)間為二維碼有效期,此隊(duì)列沒(méi)有設(shè)置消費(fèi)者,過(guò)了有效期后消息會(huì)重新路由到指定的的隊(duì)列,有消費(fèi)者去執(zhí)行訂單查詢。

RabbitMQ本身沒(méi)有直接支持延遲隊(duì)列功能,但是可以通過(guò)以下特性模擬出延遲隊(duì)列的功能。 但是我們可以通過(guò)RabbitMQ的兩個(gè)特性來(lái)曲線實(shí)現(xiàn)延遲隊(duì)列:Time To Live(TTL)   和   Dead Letter Exchanges(DLX)

Time To Live(TTL)

RabbitMQ可以針對(duì)Queue和Message設(shè)置 x-message-tt,來(lái)控制消息的生存時(shí)間,如果超時(shí),則消息變?yōu)閐ead letter(死信)RabbitMQ針對(duì)隊(duì)列中的消息過(guò)期時(shí)間有兩種方法可以設(shè)置。

A: 通過(guò)隊(duì)列屬性設(shè)置,隊(duì)列中所有消息都有相同的過(guò)期時(shí)間。

<!-- 將消息放入此隊(duì)列里,此隊(duì)列設(shè)置過(guò)期時(shí)間,不制造消費(fèi)者讓其過(guò)期,過(guò)期后變成死信,消息會(huì)放入指定的新隊(duì)列里,實(shí)現(xiàn)消息的延遲消費(fèi) -->
<rabbit:queue name="paycenter.scanpay.orderquery.delay.icbc" durable="true" auto-delete="false" exclusive="false" >
    <rabbit:queue-arguments>
        <entry key="x-message-ttl">
           <value type="java.lang.Long">${qrcode.expire.icbc}</value>
        </entry>
        <!--消息過(guò)期根據(jù)重新路由 -->
        <entry key="x-dead-letter-exchange" value="directExchange"/>
        <entry key="x-dead-letter-routing-key" value="paycenter.scanpay.orderquery"/>
    </rabbit:queue-arguments>
</rabbit:queue>

B: 對(duì)消息進(jìn)行單獨(dú)設(shè)置,每條消息TTL可以不同。

<!-- 將消息放入此隊(duì)列里,次隊(duì)列設(shè)置過(guò)期時(shí)間,不制造消費(fèi)者讓其過(guò)期,過(guò)期后變成死信,消息會(huì)放入指定的新隊(duì)列里,實(shí)現(xiàn)消息的延遲消費(fèi) -->
<rabbit:queue name="paycenter.scanpay.orderquery.delay.icbc" durable="true" auto-delete="false" exclusive="false" >
    <rabbit:queue-arguments>
        <!--消息過(guò)期根據(jù)重新路由 -->
        <entry key="x-dead-letter-exchange" value="directExchange"/>
        <entry key="x-dead-letter-routing-key" value="paycenter.scanpay.orderquery"/>
    </rabbit:queue-arguments>
</rabbit:queue>
amqpTemplate.convertAndSend(mqMessage.getExchange(), mqMessage.getRoutingKey(), result, new ExpirationMessagePostProcessor(expireTime));
package com.emax.paycenter.mq.pruducer;
 
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
 
public class ExpirationMessagePostProcessor implements MessagePostProcessor {
	private final Long ttl;
 
	public ExpirationMessagePostProcessor(Long ttl) {
		this.ttl = ttl;
	}
 
	@Override
	public Message postProcessMessage(Message message) throws AmqpException {
		message.getMessageProperties().setExpiration(ttl.toString());
		return message;
	}
}

如果同時(shí)使用,則消息的過(guò)期時(shí)間以兩者之間TTL較小的那個(gè)數(shù)值為準(zhǔn)。消息在隊(duì)列的生存時(shí)間一旦超過(guò)設(shè)置的TTL值,就成為dead letter

 Dead Letter Exchanges(DLX)

RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可選)兩個(gè)參數(shù),如果隊(duì)列內(nèi)出現(xiàn)了dead letter,則按照這兩個(gè)參數(shù)重新路由。
x-dead-letter-exchange:出現(xiàn)dead letter之后將dead letter重新發(fā)送到指定exchange
x-dead-letter-routing-key:指定routing-key發(fā)送
隊(duì)列出現(xiàn)dead letter的情況有:
消息或者隊(duì)列的TTL過(guò)期
隊(duì)列達(dá)到最大長(zhǎng)度
消息被消費(fèi)端拒絕(basic.reject or basic.nack)并且requeue=false
利用DLX,當(dāng)消息在一個(gè)隊(duì)列中變成死信后,它能被重新publish到另一個(gè)Exchange。這時(shí)候消息就可以重新被消費(fèi)。

注意一:ttl設(shè)置之后,下次修改時(shí)間,會(huì)報(bào)錯(cuò),這時(shí)候,需要先刪除該隊(duì)列,重啟項(xiàng)目。否則會(huì)報(bào)錯(cuò)。

注意二:消費(fèi)者中,拋異常了沒(méi)處理,會(huì)一直重復(fù)消費(fèi)

注意三:下面的代碼我模擬了1-10號(hào)消息,消息的內(nèi)容里面是1-10。過(guò)期的時(shí)間是10-1秒。這里要注意,雖然10是第一個(gè)發(fā)送,但是它過(guò)期的時(shí)間最長(zhǎng)。

過(guò)了10s以后,消費(fèi)者開(kāi)始收到數(shù)據(jù),但是它是一次性收到如下結(jié)果:10、9 、8 、7 、6、5 、4 、3 、2 、1
Consumer第一個(gè)收到的還是10。10是第一個(gè)放進(jìn)隊(duì)列,但是它的過(guò)期時(shí)間最長(zhǎng)。所以由此可見(jiàn),即使一個(gè)消息比在同一隊(duì)列中的其他消息提前過(guò)期,提前過(guò)期的也不會(huì)優(yōu)先進(jìn)入死信隊(duì)列,它們還是按照入庫(kù)的順序讓消費(fèi)者消費(fèi)。如果第一進(jìn)去的消息過(guò)期時(shí)間是1小時(shí),那么死信隊(duì)列的消費(fèi)者也許等1小時(shí)才能收到第一個(gè)消息。參考官方文檔發(fā)現(xiàn)“Only when expired messages reach the head of a queue will they actually be discarded (or dead-lettered).”只有當(dāng)過(guò)期的消息到了隊(duì)列的頂端(隊(duì)首),才會(huì)被真正的丟棄或者進(jìn)入死信隊(duì)列。

所以在考慮使用RabbitMQ來(lái)實(shí)現(xiàn)延遲任務(wù)隊(duì)列的時(shí)候,需要確保業(yè)務(wù)上每個(gè)任務(wù)的延遲時(shí)間是一致的。如果遇到不同的任務(wù)類(lèi)型需要不同的延時(shí)的話,需要為每一種不同延遲時(shí)間的消息建立單獨(dú)的消息隊(duì)列。(也可以考慮緩存隊(duì)列,DelayQueue實(shí)現(xiàn)定時(shí)延遲執(zhí)行任務(wù),但是也有缺點(diǎn):就是項(xiàng)目重啟緩存里的數(shù)據(jù)就會(huì)丟失,DelayQueue的使用詳見(jiàn)其他博文)

for(int i = 10; i>0; i-- ){
	amqpTemplate.convertAndSend(mqMessage.getExchange(), mqMessage.getRoutingKey(), result, new ExpirationMessagePostProcessor(expireTime));
}

到此這篇關(guān)于RabbitMQ死信機(jī)制實(shí)現(xiàn)延遲隊(duì)列的實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)RabbitMQ 延遲隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot?對(duì)接飛書(shū)多維表格事件回調(diào)監(jiān)聽(tīng)流程分析

    SpringBoot?對(duì)接飛書(shū)多維表格事件回調(diào)監(jiān)聽(tīng)流程分析

    本文介紹了如何通過(guò)飛書(shū)事件訂閱機(jī)制和SpringBoot項(xiàng)目集成,對(duì)多維表數(shù)據(jù)的記錄變更進(jìn)行對(duì)接的詳細(xì)流程,包括如何創(chuàng)建應(yīng)用、配置參數(shù)、編寫(xiě)訂閱代碼、訂閱文檔事件以及在SpringBoot工程中集成的步驟,感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • Maven項(xiàng)目更換本地倉(cāng)庫(kù)過(guò)程圖解

    Maven項(xiàng)目更換本地倉(cāng)庫(kù)過(guò)程圖解

    這篇文章主要介紹了Maven項(xiàng)目更換本地倉(cāng)庫(kù)過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 關(guān)于MyBatis中Mapper?XML熱加載優(yōu)化

    關(guān)于MyBatis中Mapper?XML熱加載優(yōu)化

    大家好,本篇文章主要講的是關(guān)于MyBatis中Mapper?XML熱加載優(yōu)化,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • Spring框架基于注解開(kāi)發(fā)CRUD詳解

    Spring框架基于注解開(kāi)發(fā)CRUD詳解

    這篇文章主要為大家詳細(xì)介紹了Spring框架基于注解開(kāi)發(fā)CRUD,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • MyBatis反向生成Example類(lèi)的使用方式

    MyBatis反向生成Example類(lèi)的使用方式

    今天小編就為大家分享一篇MyBatis反向生成Example類(lèi)的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java項(xiàng)目防止SQL注入的幾種方法總結(jié)

    Java項(xiàng)目防止SQL注入的幾種方法總結(jié)

    SQL注入是比較常見(jiàn)的網(wǎng)絡(luò)攻擊方式之一,在客戶端在向服務(wù)器發(fā)送請(qǐng)求的時(shí)候,sql命令通過(guò)表單提交或者url字符串拼接傳遞到后臺(tái)持久層,最終達(dá)到欺騙服務(wù)器執(zhí)行惡意的SQL命令,下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java項(xiàng)目防止SQL注入的幾種方法,需要的朋友可以參考下
    2023-04-04
  • IntelliJ IDEA最佳配置(推薦)

    IntelliJ IDEA最佳配置(推薦)

    這篇文章主要介紹了IntelliJ IDEA最佳配置,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Netty學(xué)習(xí)之理解selector原理示例

    Netty學(xué)習(xí)之理解selector原理示例

    這篇文章主要為大家介紹了Netty學(xué)習(xí)之理解selector原理示例使用分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2023-07-07
  • springboot使用redisTemplate操作lua腳本

    springboot使用redisTemplate操作lua腳本

    本文主要介紹了springboot使用redisTemplate操作lua腳本,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Log4j2?重大漏洞編譯好的log4j-2.15.0.jar包下載(替換過(guò)程)

    Log4j2?重大漏洞編譯好的log4j-2.15.0.jar包下載(替換過(guò)程)

    Apache?開(kāi)源項(xiàng)目?Log4j?的遠(yuǎn)程代碼執(zhí)行漏洞細(xì)節(jié)被公開(kāi),由于?Log4j?的廣泛使用,該漏洞一旦被攻擊者利用會(huì)造成嚴(yán)重危害,下面小編給大家?guī)?lái)了Log4j2?重大漏洞編譯好的log4j-2.15.0.jar包下載,感興趣的朋友一起看看吧
    2021-12-12

最新評(píng)論

临潭县| 修水县| 邵东县| 雷波县| 焉耆| 富顺县| 桂阳县| 南雄市| 临沭县| 汽车| 惠州市| 漳浦县| 特克斯县| 阳新县| 霍州市| 呼玛县| 恩施市| 津南区| 沂水县| 新民市| 太湖县| 新兴县| 辛集市| 行唐县| 沽源县| 瓦房店市| 南郑县| 马边| 锡林郭勒盟| 西城区| 怀宁县| 沧源| 平顶山市| 马鞍山市| 和顺县| 临江市| 嘉峪关市| 阳谷县| 高邑县| 兴文县| 西丰县|