RabbitMQ筆記二十:Dead Letter Exchange

Dead Letter Exchange

在隊(duì)列上指定一個(gè)Exchange,則在該隊(duì)列上發(fā)生如下情況,
1.消息被拒絕(basic.reject or basic.nack)系洛,且requeue=false
2.消息過(guò)期而被刪除(TTL)
3.消息數(shù)量超過(guò)隊(duì)列最大限制而被刪除
4.消息總大小超過(guò)隊(duì)列最大限制而被刪除

就會(huì)把該消息轉(zhuǎn)發(fā)到指定的這個(gè)exchange
同時(shí)也可以指定一個(gè)可選的x-dead-letter-routing-key而晒,表示默認(rèn)的routing-key,如果沒(méi)有指定,則使用消息的routeing-key(也跟指定的exchange有關(guān)蜡娶,
如果是Fanout類型的exchange混卵,則會(huì)轉(zhuǎn)發(fā)到所有綁定到該exchange的所有隊(duì)列)。

拒絕消息或者nack

示列

定義一個(gè)隊(duì)列zhihao.miao.order窖张,其有屬性x-dead-letter-exchangezhihao.miao.exchange.pay幕随,往Exchange名為zhihao.miao.exchange.order中發(fā)送消息。

zhihao.miao.order隊(duì)列中發(fā)送消息宿接,

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.concurrent.TimeUnit;

@ComponentScan
public class Application {
    public static void main(String[] args) throws Exception{
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
        RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);

        byte[] body = "hello,zhihao.miao".getBytes();

        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setContentType("json");

        Message message = new Message(body,messageProperties);

        rabbitTemplate.send("zhihao.miao.exchange.order","zhihao.miao.order",message);

        TimeUnit.SECONDS.sleep(30);

        context.close();
    }
}

配置類:

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MQConfig {

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setUri("amqp://zhihao.miao:123456@192.168.1.131:5672");
        return factory;
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        return rabbitAdmin;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        return rabbitTemplate;
    }

}

此時(shí)消息端拒絕消費(fèi)這個(gè)消息

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.concurrent.TimeUnit;

@ComponentScan
public class Application {
    public static void main(String[] args) throws Exception{
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
        RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);

        System.out.println(rabbitTemplate);

        TimeUnit.SECONDS.sleep(30);

        context.close();
    }
}

配置類

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MQConfig {

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setUri("amqp://zhihao.miao:123456@192.168.1.131:5672");
        return factory;
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        return rabbitAdmin;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        return rabbitTemplate;
    }


    @Bean
    public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory){
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("zhihao.miao.order");
        container.setDefaultRequeueRejected(false);
        //手動(dòng)確認(rèn)
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        container.setMessageListener(new ChannelAwareMessageListener(){
            @Override
            public void onMessage(Message message, Channel channel) throws Exception {
                System.out.println("=====rece msg======");
                System.out.println(new String(message.getBody()));
                //執(zhí)行拒絕消息
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }
        });
        return container;
    }
}

因?yàn)槠渲付?code>x-dead-letter-exchange是zhihao.miao.exchange.pay赘淮,所以會(huì)將消息轉(zhuǎn)發(fā)到zhihao.miao.exchange.pay,而因?yàn)闆](méi)有指定x-dead-letter-routing-key睦霎,所以會(huì)使用默認(rèn)的發(fā)送的消息的route key(zhihao.miao.order)進(jìn)行路由梢卸,而我們zhihao.miao.exchange.pay的路由信息如下,所以會(huì)將消息轉(zhuǎn)發(fā)到zhihao.miao.auto隊(duì)列中去副女。

zhihao.miao.exchange.pay的路由信息
發(fā)送二條消息蛤高,執(zhí)行了拒絕策略,所以消息轉(zhuǎn)發(fā)到了zhihao.miao.auto隊(duì)列中

示列2

定義了隊(duì)列zhihao.miao.order碑幅,不僅定義了x-dead-letter-exchange屬性戴陡,也指定了x-dead-letter-routing-key屬性

隊(duì)列zhihao.miao.order定義
zhihao.miao.exchange.pay的路由信息

顯而易見(jiàn)當(dāng)拒絕了該消息的時(shí)候就會(huì)轉(zhuǎn)發(fā)到了zhihao.miao.exchange.pay,而應(yīng)該該隊(duì)列指定了route key為zhihao.miao.pay沟涨,所以轉(zhuǎn)發(fā)到了zhihao.miao.pay隊(duì)列中去了恤批。

代碼很上面的一樣。

總結(jié)

上面的示列展示了當(dāng)定義隊(duì)列時(shí)指定了x-dead-letter-exchangex-dead-letter-routing-key視情況而定)裹赴,并且消費(fèi)端執(zhí)行拒絕策略的時(shí)候?qū)⑾⒙酚傻街付ǖ腅xchange中去喜庞。我們知道還有二種情況會(huì)造成消息轉(zhuǎn)發(fā)到死信隊(duì)列。
一種是消息過(guò)期而被刪除棋返,可以使用這個(gè)方式使的rabbitmq實(shí)現(xiàn)延遲隊(duì)列的作用延都。還有一種就是消息數(shù)量超過(guò)隊(duì)列最大限制而被刪除或者消息總大小超過(guò)隊(duì)列最大限制而被刪除

參考資料

Dead Letter Exchanges
使用TTL(消息過(guò)期)來(lái)實(shí)現(xiàn)消息延遲

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市懊昨,隨后出現(xiàn)的幾起案子窄潭,更是在濱河造成了極大的恐慌,老刑警劉巖酵颁,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫉你,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡躏惋,警方通過(guò)查閱死者的電腦和手機(jī)幽污,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)簿姨,“玉大人距误,你說(shuō)我怎么就攤上這事簸搞。” “怎么了准潭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵趁俊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我刑然,道長(zhǎng)寺擂,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任泼掠,我火速辦了婚禮怔软,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘择镇。我一直安慰自己挡逼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布腻豌。 她就那樣靜靜地躺著家坎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪饲梭。 梳的紋絲不亂的頭發(fā)上乘盖,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音憔涉,去河邊找鬼。 笑死析苫,一個(gè)胖子當(dāng)著我的面吹牛兜叨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衩侥,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼国旷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了茫死?” 一聲冷哼從身側(cè)響起跪但,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎峦萎,沒(méi)想到半個(gè)月后屡久,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爱榔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年被环,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片详幽。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筛欢,死狀恐怖浸锨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情版姑,我是刑警寧澤柱搜,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站剥险,受9級(jí)特大地震影響聪蘸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜炒嘲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一宇姚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夫凸,春花似錦浑劳、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至鸽扁,卻和暖如春蒜绽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桶现。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工躲雅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骡和。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓相赁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親慰于。 傳聞我的和親對(duì)象是個(gè)殘疾皇子钮科,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容