2.RabbitMQ運行流程

文章參考:Rabbit實戰(zhàn)指南

交換機的類型

  • fanout
    • 它會把所有發(fā)送到該交換機的消息路由到所有與該交換機綁定的隊列中伶椿。
  • direct
    • 它會把消息路由到那些BindingKey和RoutingKey完全匹配的隊列中辜伟。
  • topic
    • 將消息路由到BindingKey和RoutingKey相匹配的隊列中,它約定:
      • RoutingKey作為一個點號"."分割的字符串(被點號"."分隔開的每一段獨立的字符串稱為一個單詞)
      • BindingKey和RoutingKey一樣也是點號"."分割的字符串脊另。
      • BindingKey中可以存在兩種特殊字符串"*"和"#"导狡,用于做模糊匹配,其中"#"用來匹配一個單詞偎痛,"*"用于匹配多規(guī)格單詞旱捧。
        • 路由鍵為“com.rabbitmq.client”的消息會同時路由到Queue1和Queue2;
        • 路由鍵為“com.hidden.client”的消息只會路由到Queue2中;
        • 路由鍵為java.util.concurrent的消息會被丟棄或者返回給生產(chǎn)者(需要設(shè)置)
  • headers
    • headers類型的交換機不依賴路由鍵的匹配規(guī)則來路由信息踩麦,而是根據(jù)發(fā)送的消息內(nèi)容中的headers屬性進行匹配枚赡。在綁定隊列和交換器時制定一組鍵值對,當發(fā)送信息到交換器時谓谦,RabbitMQ會獲取到該信息的headers贫橙,對比其中鍵值對是否完全匹配隊列和交換器綁定時指定的鍵值對,如果完全匹配則消息會路由到該隊列反粥。

RabbitMQ運轉(zhuǎn)流程

  • 生產(chǎn)者發(fā)送消息:
    1. 生產(chǎn)者連接到RabbitMQ Broker卢肃,建立一個連接(Connection),開啟一個信道(Channel)
    2. 生產(chǎn)者聲明一個交換器才顿,并設(shè)置相關(guān)屬性莫湘,比如交互器類型,是否持久化等
    3. 生產(chǎn)者聲明一個隊列并設(shè)置相關(guān)屬性郑气,比如是否排他幅垮,是否持久化,是否自動刪除等
    4. 生產(chǎn)者通過路由鍵將交換器和隊列綁定起來
    5. 生產(chǎn)者發(fā)送消息至RabbitMQ Broker尾组,其中包含路由鍵忙芒,交換器等信息
    6. 相應的交換器根據(jù)接受到的路由鍵查找相匹配的隊列
    7. 如果找到,則將從生產(chǎn)者發(fā)送過來的信息存入相應的隊列中
    8. 如果沒有找到讳侨,則根據(jù)生產(chǎn)者配置的屬性選擇丟棄還是回退給生產(chǎn)者
    9. 關(guān)閉信道
    10. 關(guān)閉連接
  • 消費者接受消息:
    1. 消費者連接到RabbitMQ Broker匕争,建立一個連接,開啟一個信道
    2. 消費者向RabbitMQ Broker 請求消費相應隊列中的消息爷耀,可能會設(shè)置相應的回調(diào)函數(shù)甘桑,以及做一些準備工作
    3. 等待RabbitMQ Broker 回應并投遞相應隊列中的消息,消費者接受消息
    4. 消費者確認接收到的消息
    5. RabbitMQ從隊列中刪除相應已經(jīng)被確認的消息
    6. 關(guān)閉信道
    7. 關(guān)閉連接

連接RabbitMQ

下面代碼用來在給定的參數(shù)(IP地址歹叮、端口號跑杭、用戶名、密碼等)下連接RabbitMQ:
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername(USERNAME);
factory.setPassword(PASSWORD);
factory.setVirtualHost(virtualHost);
factory.setHost(IP_ADDRESS);
factory.setPort(PORT);
Connection conn = factory.newConnection();

也可以選擇使用URI的方式來實現(xiàn)咆耿,
ConnectionFactory factory = new ConnectionFactory();
factory.setUri("amqp://userName:password@ipAddress:portNumber/virtualHost");
Connection conn = factory.newConnection();
創(chuàng)建之后德谅,Channel可以用來發(fā)送或者接收消息了。
Channel channel = conn.createChannel();

Channel或者Connection中有個isOpen方法可以用來檢測其是否處于開啟狀態(tài)萨螺,不推薦在生產(chǎn)環(huán)境上使用isOpen方法窄做,這個方法的返回值依賴于shutdownCause的存在愧驱,有可能會產(chǎn)生競爭。

isOpen方法的源碼
public boolean isOpen(){
    synchronized(this.monitor){
        return this.shutdownCause == null;
    }
}
錯誤的使用isOpen方法
public void brokenMethod(Channel channel){
    if(channel.isOpen()){
        //The following code depends on the channel being in open state.
        //However there is a possibility of the change in the channel state
        //between isOpen() and basicQos(1) call
        ...
        channel.baseicQos(1);
    }
}

通常情況下椭盏,在調(diào)用createXXX或者newXXX方法之后组砚,我們可以簡單地認為Connection或者Channel已經(jīng)成功地處于開啟狀態(tài),而并不會在代碼中使用isOpen這個檢測方法掏颊。如果在使用Channel的時候其已經(jīng)處于關(guān)閉狀態(tài)糟红,那么程序會拋出個 com. rabbitmq. client. ShutdownSignalException,我們只需捕獲這個異常即可。當然同時也要試著捕獲I0Exception 或者SocketException, 以防Connection意外關(guān)閉乌叶。示例代碼如下:

public void validMethod(Channel channel){
    try{
        ...
        channel.basicQos(1);
    } catch (ShutdownSignalException sse){
        //possibly check if channel was closed 
        //by the time we started action and reasons for 
        //closing it
        ...
    } catch (IOException ioe) {
        // check why connection was closed
        ...
    }
}
最后編輯于
?著作權(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)自己被綠了斩个。 大學時的朋友給我發(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