rabbitMQ-延時(shí)隊(duì)列

延時(shí)隊(duì)列我們可以簡(jiǎn)單粗暴的理解它為延時(shí)發(fā)送消息的隊(duì)列

好家伙,相當(dāng)粗暴

那延時(shí)隊(duì)列的應(yīng)用場(chǎng)景有哪些呢飞几,比如訂單在一段時(shí)間內(nèi)未支付則取消訂單掏击,就是需要在某個(gè)事件發(fā)生之后或者之前的某個(gè)時(shí)間點(diǎn)完成另一事件。
這種場(chǎng)景講道理可以用定時(shí)器來完成泵琳,但是如果有些事件的時(shí)間點(diǎn)需要精確到秒真屯,我們就需要每秒輪詢一次,或者在數(shù)據(jù)量較大的時(shí)候倍试,定時(shí)器可能需要跑很久讯屈,給系統(tǒng)帶來很大壓力!(好了就這把县习,編不下去了涮母。。QAQ
那rabbitMQ的TTL只是消息在隊(duì)列中的存活時(shí)間准颓,并不是說消息在存活一段時(shí)間后才會(huì)發(fā)送給消費(fèi)者哈蝇,所以并不能只用TTL來實(shí)現(xiàn)延時(shí)隊(duì)列,還需要借助死信隊(duì)列攘已。
大致流程

生產(chǎn)者發(fā)送一條延時(shí)消息到延時(shí)隊(duì)列炮赦,當(dāng)消息過期又會(huì)被路由到死信隊(duì)列,消費(fèi)者只要監(jiān)聽死信隊(duì)列即可样勃。

配置類
@Configuration
public class DelayMQConfig {
    /**
     * 延時(shí)隊(duì)列交換機(jī)
     */
    public static final String DELAY_EXCHANGE_NAME = "delay.exchange";
    /**
     * 延時(shí)隊(duì)列
     */
    public static final String DELAY_QUEUE_NAME = "delay.queue";
    /**
     * 死信交換機(jī)
     */
    public static final String DEAD_EXCHANGE_NAME = "dead.exchange";
    /**
     * 死信隊(duì)列
     */
    public static final String DEAD_QUEUE_NAME = "dead.queue";

    /**
     * 聲明延時(shí)交換機(jī)
     */
    @Bean("delayExchange")
    public DirectExchange delayExchange(){
        return new DirectExchange(DELAY_EXCHANGE_NAME);
    }

    /**
     * 聲明延時(shí)隊(duì)列吠勘,并綁定到死信交換機(jī)上
     */
    @Bean("delayQueue")
    public Queue delayQueue(){
        Map<String, Object> args = new HashMap<>(2);
        //綁定死信交換機(jī)
        args.put("x-dead-letter-exchange", DEAD_EXCHANGE_NAME);
        //路由
        args.put("x-dead-letter-routing-key", "dead.routing.key");
        //延時(shí)10S
        args.put("x-message-ttl", 10000);
        return QueueBuilder.durable(DELAY_QUEUE_NAME).withArguments(args).build();
    }

    /**
     * 延時(shí)隊(duì)列綁定到延時(shí)隊(duì)列交換機(jī)
     *
    **/
    @Bean
    public Binding delayBinding(@Qualifier("delayQueue")Queue queue,
                                @Qualifier("delayExchange")DirectExchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("delay.routing.key");
    }

    /**
     * 聲明死信交換機(jī)
     */
    @Bean("deadExchange")
    public DirectExchange deadExchange(){
        return new DirectExchange(DEAD_EXCHANGE_NAME);
    }

    @Bean("deadQueue")
    public Queue deadQueue(){
        return new Queue(DEAD_QUEUE_NAME);
    }

    @Bean
    public Binding deadBinding(@Qualifier("deadQueue")Queue queue,
                               @Qualifier("deadExchange")DirectExchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("dead.routing.key");
    }
}

截圖看一下其中一個(gè)

延時(shí)隊(duì)列
消費(fèi)者
@Component
public class DelayListener {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @RabbitListener(queues = DelayMQConfig.DEAD_QUEUE_NAME)
    public void receive(Message message, Channel channel) throws Exception{
        String msg = new String(message.getBody());
        logger.info("收到消息的時(shí)間:{},收到的消息內(nèi)容:{}", new Date().toString(), msg);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}
生產(chǎn)者
    @PostMapping("delayMsgSend")
    public void delayMsgSend(@RequestParam("msg")String msg){
        rabbitTemplate.convertSendAndReceive(DelayMQConfig.DELAY_EXCHANGE_NAME,"delay.routing.key",msg);
    }

發(fā)送一個(gè)消息峡眶,日志如下

2020-10-13 10:47:05.465  INFO 44044 --- [nio-9000-exec-1] com.lyy.study.controller.MyController    : 發(fā)送消息的時(shí)間:Tue Oct 13 10:47:05 CST 2020剧防,發(fā)送的消息內(nèi)容:delayMsgSend
2020-10-13 10:47:05.532  INFO 44044 --- [nio-9000-exec-1] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService
2020-10-13 10:47:05.545  INFO 44044 --- [nio-9000-exec-1] .l.DirectReplyToMessageListenerContainer : Container initialized for queues: [amq.rabbitmq.reply-to]
2020-10-13 10:47:05.627  INFO 44044 --- [nio-9000-exec-1] .l.DirectReplyToMessageListenerContainer : SimpleConsumer [queue=amq.rabbitmq.reply-to, consumerTag=amq.ctag-KMeIYI6Pcun_gzAm5AYe3w identity=49703e41] started
2020-10-13 10:47:15.675  INFO 44044 --- [ntContainer#0-1] com.lyy.study.mq.listener.DelayListener  : 收到消息的時(shí)間:Tue Oct 13 10:47:15 CST 2020,收到的消息內(nèi)容:delayMsgSend

到此一個(gè)簡(jiǎn)單的延時(shí)隊(duì)列就實(shí)現(xiàn)了辫樱。

(●'?'●)

不過更多的時(shí)候峭拘,我們其實(shí)需要的是給每一個(gè)消息添加自己的TTL,那么就會(huì)有一個(gè)問題拉,假如我們先發(fā)送了一個(gè)10S的延時(shí)消息鸡挠,又發(fā)送了一個(gè)5S的延時(shí)消息辉饱,預(yù)期的結(jié)果應(yīng)該是先消費(fèi)5S的那個(gè)消息,然而實(shí)際的結(jié)果是10S的消息先被消費(fèi)了拣展,才會(huì)消費(fèi)5S的那個(gè)消息(這個(gè)問題在TTL那篇文章有提過)彭沼,那怎么辦呢?

撓頭

不要慌备埃,https://www.rabbitmq.com/community-plugins.html從官網(wǎng)上下載一個(gè)叫rabbitmq_delayed_message_exchange的插件就好了姓惑!
rabbitmq_delayed_message_exchange插件

下載之后解壓放到rabbitMQ的插件目錄
插件目錄

然后進(jìn)入sbin目錄,執(zhí)行以下命令
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
重啟就OK了按脚!
驗(yàn)證的部分我就不寫了于毙,懶惰.jpg

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辅搬,隨后出現(xiàn)的幾起案子望众,更是在濱河造成了極大的恐慌,老刑警劉巖伞辛,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異夯缺,居然都是意外死亡蚤氏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門踊兜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來竿滨,“玉大人,你說我怎么就攤上這事捏境∮谟危” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵垫言,是天一觀的道長贰剥。 經(jīng)常有香客問我,道長筷频,這世上最難降的妖魔是什么蚌成? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮幽勒,結(jié)果婚禮上梦皮,老公的妹妹穿的比我還像新娘岗喉。我一直安慰自己,他們只是感情好瓶盛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般惩猫。 火紅的嫁衣襯著肌膚如雪芝硬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天帆锋,我揣著相機(jī)與錄音吵取,去河邊找鬼。 笑死锯厢,一個(gè)胖子當(dāng)著我的面吹牛皮官,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播实辑,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼捺氢,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了剪撬?” 一聲冷哼從身側(cè)響起摄乒,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎残黑,沒想到半個(gè)月后馍佑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡梨水,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年拭荤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疫诽。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舅世,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奇徒,到底是詐尸還是另有隱情雏亚,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布摩钙,位于F島的核電站罢低,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏腺律。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一匀钧、第九天 我趴在偏房一處隱蔽的房頂上張望翎碑。 院中可真熱鬧,春花似錦之斯、人聲如沸日杈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莉擒。三九已至酿炸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涨冀,已是汗流浹背填硕。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鹿鳖,地道東北人扁眯。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像翅帜,于是被迫代替她去往敵國和親姻檀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349