Destination高級特性

長恨人生不如水隆圆,等閑平地起波瀾抹凳。 —— 劉禹錫

1. Wildcards(通配符)

??Wildcars用來支持名字分層體系漂彤,它不是JMS規(guī)范的一部分鸯匹,是ActiveMQ的擴展坊饶。
??ActiveMQ支持以下三種通配符:

  • ".":用于作為路徑上名字間的分隔符
  • ">":用于遞歸的匹配任何以這個名字開始的Destination(目的地)
  • "*":用于作為路徑上任何名字。

??舉例來說殴蓬,如有以下兩個Destination:
??PRICE.COMPUTER.JD.APPLE(蘋果電腦在京東上的價格)
??PRICE.COMPUTER.TMALL.APPLE(蘋果電腦在天貓上的價格)

??1. PRICE.> :匹配任何產(chǎn)品的價格變動
??2. PRICE.COMPUTER.> :匹配任何電腦產(chǎn)品的價格變動
??3. PRICE.COMPUTER.JD.*:匹配任何在京東上的電腦的價格變動
??4. PRICE.COMPUTER.*.APPLE:匹配蘋果電腦京東或天貓上的價格變動
??JAVA代碼示例:
??生產(chǎn)者:

// 實例化連接工廠
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, "failover:(tcp://localhost:61616,tcp://localhost:61617)?randomize=false");
// 通過連接工廠獲取連接
Connection connection = connectionFactory.createConnection();
// 啟動連接
connection.start();
// 創(chuàng)建session
Session session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);
// 創(chuàng)建隊列
Destination destination = session.createQueue("PRICE.COMPUTER.JD.APPLE");
// 創(chuàng)建生產(chǎn)者
MessageProducer messageProducer = session.createProducer(destination);
for (int i = 1; i <= 10; i++) {
    TextMessage textMessage = session.createTextMessage(message);
    messageProducer.send("Mac Air價格:"  + i * 1000);
    System.out.println("發(fā)送消息 - " + textMessage.getText());
}
session.commit();

??消費者:

// 實例化連接工廠
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, "failover:(tcp://localhost:61616,tcp://localhost:61617)?randomize=false");
// 通過連接工廠獲取連接
Connection connection = connectionFactory.createConnection();
// 啟動連接
connection.start();
// 創(chuàng)建session
Session session = connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);
// 創(chuàng)建隊列
Destination destination = session.createQueue("PRICE.COMPUTER.>");
// 創(chuàng)建消費者
MessageConsumer messageConsumer = session.createConsumer(destination);
messageConsumer.setMessageListener(new MessageListener(){
  @Override
    public void onMessage(Message message) {
        try {
            System.out.println("收到的消息:" + ((TextMessage) message).getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
});

??生產(chǎn)者發(fā)送消息日志:

發(fā)送消息:Mac Air價格:1000
發(fā)送消息:Mac Air價格:2000
發(fā)送消息:Mac Air價格:3000
發(fā)送消息:Mac Air價格:4000
發(fā)送消息:Mac Air價格:5000
發(fā)送消息:Mac Air價格:6000
發(fā)送消息:Mac Air價格:7000
發(fā)送消息:Mac Air價格:8000
發(fā)送消息:Mac Air價格:9000
發(fā)送消息:Mac Air價格:10000

??消費者接收到的消息日志:

收到的消息:Mac Air價格:1000
收到的消息:Mac Air價格:2000
收到的消息:Mac Air價格:3000
收到的消息:Mac Air價格:4000
收到的消息:Mac Air價格:5000
收到的消息:Mac Air價格:6000
收到的消息:Mac Air價格:7000
收到的消息:Mac Air價格:8000
收到的消息:Mac Air價格:9000
收到的消息:Mac Air價格:10000

??從消費者的接收日志來看匿级,當消費者使用通配符隊列時,是能正常接收消息的染厅。

通配符中是為消費者服務(wù)的痘绎。即:通配符只能配置在消費端。

2. 組合列隊(Composite Destinations)

??組合列隊即通過一個虛擬的Destination代表多個Destination肖粮,這樣就可以通過該虛擬的Destination同時向多個Destination發(fā)送消息孤页。
??實現(xiàn)虛擬Destination可通過以下方式實現(xiàn):
??(1) 客戶端方式
??生產(chǎn)者:

Destination destination = session.createQueue("PRICE.COMPUTER.JD.APPLE,PRICE.COMPUTER.TMALL.APPLE");
// 多個Destination使用,分隔

??消費者:

Destination destination = session.createQueue("PRICE.COMPUTER.JD.APPLE");
// 或者
Destination destination = session.createQueue("PRICE.COMPUTER.TMALL.APPLE");

// 以上兩個消費者都能接收到生產(chǎn)者的消息

若使用不同類型的destination,那么需要加上前綴如queue:// 或topic://涩馆。如:Destination destination = session.createQueue("PRICE.COMPUTER.JD.APPLE,topic://PRICE.COMPUTER.TMALL.APPLE");

??(2) 配置方式
??在activemq.xml的broker中添加以下配置:

<destinationInterceptors>
    <virtualDestinationInterceptor>
        <virtualDestinations>
            <compositeQueue name="PRICE.COMPUTER">
                  <forwardTo>
                    <queue physicalName="PRICE.COMPUTER.JD.APPLE"/>
                    <queue physicalName="PRICE.COMPUTER.TMALL.APPLE" />
                   </forwardTo>
            </compositeQueue>
        </virtualDestinations>
     </virtualDestinationInterceptor>
</destinationInterceptors>

??然后在生產(chǎn)者中行施,直接向隊列PRICE.COMPUTER中發(fā)送消息。那么監(jiān)聽PRICE.COMPUTER.JD.APPLE或PRICE.COMPUTER.TMALL.APPLE的消費者都能同時接收到生產(chǎn)者發(fā)送的消息魂那。

注意:修改完配置文件后蛾号,須重啟Broker服務(wù),不然配置是不會生效的涯雅!

3. 配置啟動隊列

??若需要在ActiveMQ啟動的時候鲜结,創(chuàng)建Destination的話,可以如下配置conf/activemq.xml的broker下:

<destinations>
    <queue physicalName="PRICE.COMPUTER.JD.APPLE" />
    <topic physicalName="PRICE.COMPUTER.TMALL.APPLE" />
</destinations>

4. 隊列選項

??隊列選項是給consumer在JMS規(guī)范之外添加的功能特性活逆,通過在隊列名稱后面使用類似URL的語法添加多個選項精刷。包括:
?? 1:consumer.prefetchSize,consumer持有的未確認最大消息數(shù)量划乖,默認值 variable贬养。
?? 2:consumer.maximumPendingMessageLimit:用來控制非持久化的topic在存在慢消費者的情況下,丟棄的數(shù)量,默認0宋欺。
??3:consumer.noLocal :默認false。
?? 4:consumer.dispatchAsync :是否異步分發(fā) 蔚晨,默認true儿礼。
??5:consumer.retroactive:是否為回溯消費者 咖杂,默認false。
?? 6:consumer.selector:Jms的Selector蚊夫,默認null诉字。
?? 7:consumer.exclusive:是否為獨占消費者 ,默認false知纷。
?? 8:consumer.priority:設(shè)置消費者的優(yōu)先級壤圃,默認0。

??示例如下:

queue = new ActiveMQQueue("PRICE.COMPUTER.TMALL.APPLE?consumer.dispatchAsync=true&consumer.prefetchSize=20");
consumer = session.createConsumer(queue);

5. 虛擬Destination

??ActiveMQ支持虛擬Destination有以下兩種方式:
??(1) 虛擬主題
??(2) 組合Destinations(前面已介紹過)

5.1 為何使用虛擬主題

??ActiveMQ中琅轧,topic只有在持久訂閱下才是持久化的伍绳。持久訂閱時,每個持久訂閱者乍桂,都相當于一個queue的客戶端冲杀,它會收取所有消息。這種情況下存在兩個問題:
??(1) 同一應(yīng)用內(nèi)consumer端負載均衡的問題:即同一個應(yīng)用上的一個持久訂閱不能使用多個consumer來共同承擔消息處理功能睹酌。因為每個consumer都會獲取所有消息权谁。queue模式可以解決這個問題,但broker端又不能將消息發(fā)送到多個應(yīng)用端憋沿。
??(2) 由于只能使用單個的持久訂閱者旺芽,如果這個訂閱者出錯,則應(yīng)用就無法處理消息了卤妒,系統(tǒng)的健壯性不高甥绿。

??在ActiveMQ,可以通過虛擬主題來解決以上兩個問題则披。

5.2 虛擬主題的使用

??對于消息發(fā)布者來說共缕,就是一個正常的Topic,名稱以VirtualTopic.開頭士复。例如VirtualTopic.Mobile图谷。示例:

Topic destination = session.createTopic("VirtualTopic.Mobille");

??對于消息接收端來說,是個隊列阱洪,不同應(yīng)用里使用不同的前綴作為隊列的名稱便贵,即可表明自己的身份即可實現(xiàn)消費端應(yīng)用分組。如Consumer.A.VirtualTopic.Mobille冗荸,說明它是名稱為A的消費端承璃,同理Consumer.B.VirtualTopic.Mobille說明是一個名稱為B的客戶端“霰荆可以在同一個應(yīng)用里使用多個consumer消費此Topic盔粹,則可以實現(xiàn)上面兩個功能隘梨。又因為不同應(yīng)用使用的queue名稱不同(前綴不同),所以不同的應(yīng)用中都可以接收到全部的消息舷嗡。代碼示例如下:
??應(yīng)用A的消費者:

Destination destination = session.createQueue("Consumer.A.VirtualTopic.Mobile");

應(yīng)用A的消費者啟動兩個及以上轴猎,下面稱為A1、A2.

??應(yīng)用B的消費者:

Destination destination = session.createQueue("Consumer.B.VirtualTopic.Mobile");

??應(yīng)用A的消費者和應(yīng)用B的消費者依次啟動訂閱进萄,發(fā)布者發(fā)送消息捻脖。

??應(yīng)用A消費者A1消費消息日志:

收到的消息:ActiveMQ 發(fā)送的消息:10
收到的消息:ActiveMQ 發(fā)送的消息:12
收到的消息:ActiveMQ 發(fā)送的消息:14
收到的消息:ActiveMQ 發(fā)送的消息:16
收到的消息:ActiveMQ 發(fā)送的消息:18

??應(yīng)用A消費者A2消費消息日志:

收到的消息:ActiveMQ 發(fā)送的消息:11
收到的消息:ActiveMQ 發(fā)送的消息:13
收到的消息:ActiveMQ 發(fā)送的消息:15
收到的消息:ActiveMQ 發(fā)送的消息:17
收到的消息:ActiveMQ 發(fā)送的消息:19

??應(yīng)用B消費者消息日志:

收到的消息:ActiveMQ 發(fā)送的消息:10
收到的消息:ActiveMQ 發(fā)送的消息:11
收到的消息:ActiveMQ 發(fā)送的消息:12
收到的消息:ActiveMQ 發(fā)送的消息:13
收到的消息:ActiveMQ 發(fā)送的消息:14
收到的消息:ActiveMQ 發(fā)送的消息:15
收到的消息:ActiveMQ 發(fā)送的消息:16
收到的消息:ActiveMQ 發(fā)送的消息:17
收到的消息:ActiveMQ 發(fā)送的消息:18
收到的消息:ActiveMQ 發(fā)送的消息:19

??從以上消費者日志可以看出,應(yīng)用A的A1中鼠、A2兩個消費者共同消費了10條消息可婶,而應(yīng)用B的消費者也同樣消費了10條消息,但應(yīng)用B只要一個消費者援雇。

注意:若是activemq.xml中配置了destinationInterceptors扰肌,則需要將destinationInterceptors刪除,然后重啟Broker服務(wù)熊杨。

??虛擬主題的前綴默認是VirtualTopic,若是需要修改盗舰,可通過以下方式修改:

<destinationInterceptors>
        <virtualDestinationInterceptor>
            <virtualDestinations>
                <virtualTopic name=">" prefix="VirtualTopicConsumers.*." selectorAware="false"/>
            </virtualDestinations>
        </virtualDestinationInterceptor>
</destinationInterceptors>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末晶府,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子钻趋,更是在濱河造成了極大的恐慌川陆,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛮位,死亡現(xiàn)場離奇詭異较沪,居然都是意外死亡,警方通過查閱死者的電腦和手機失仁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門尸曼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萄焦,你說我怎么就攤上這事控轿。” “怎么了拂封?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵茬射,是天一觀的道長。 經(jīng)常有香客問我冒签,道長在抛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任萧恕,我火速辦了婚禮刚梭,結(jié)果婚禮上肠阱,老公的妹妹穿的比我還像新娘。我一直安慰自己望浩,他們只是感情好辖所,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著磨德,像睡著了一般缘回。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上典挑,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天酥宴,我揣著相機與錄音,去河邊找鬼您觉。 笑死拙寡,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的琳水。 我是一名探鬼主播肆糕,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼在孝!你這毒婦竟也來了诚啃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤私沮,失蹤者是張志新(化名)和其女友劉穎始赎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仔燕,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡造垛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了晰搀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片五辽。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖厕隧,靈堂內(nèi)的尸體忽然破棺而出奔脐,到底是詐尸還是另有隱情,我是刑警寧澤吁讨,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布髓迎,位于F島的核電站,受9級特大地震影響建丧,放射性物質(zhì)發(fā)生泄漏排龄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望橄维。 院中可真熱鬧尺铣,春花似錦、人聲如沸争舞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竞川。三九已至店溢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間委乌,已是汗流浹背床牧。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遭贸,地道東北人戈咳。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像壕吹,于是被迫代替她去往敵國和親著蛙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理耳贬,服務(wù)發(fā)現(xiàn)册踩,斷路器,智...
    卡卡羅2017閱讀 134,693評論 18 139
  • 1效拭、前言 之前我們通過兩篇文章(架構(gòu)設(shè)計:系統(tǒng)間通信(19)——MQ:消息協(xié)議(上)、架構(gòu)設(shè)計:系統(tǒng)間通信(20)...
    境里婆娑閱讀 1,887評論 0 4
  • 一胖秒、 消息隊列概述 消息隊列中間件是分布式系統(tǒng)中重要的組件缎患,主要解決應(yīng)用耦合、異步消息阎肝、流量削鋒等問題挤渔。實現(xiàn)高性能...
    步積閱讀 56,965評論 10 138
  • 背景介紹 Kafka簡介 Kafka是一種分布式的,基于發(fā)布/訂閱的消息系統(tǒng)风题。主要設(shè)計目標如下: 以時間復(fù)雜度為O...
    高廣超閱讀 12,841評論 8 167
  • 懷孕后的身體體力大不如從前判导,只能用這種簡單粗暴的方式制作著一本屬于我家的畫集,成為歲月中最美的回憶沛硅。
    老酸筍閱讀 589評論 0 7