【MQ】初始MQ


title: 【MQ】初始MQ
date: 2017-12-08 21:48:26
tags: MQ
categories: MQ


接觸 MQ 之前簡單的理解消息隊列就是一個理論上無限大的線性表洽损,接觸后發(fā)現(xiàn) MQ 支持的功能遠不止這些厦取。MQ 的功能可以概括為:削峰填谷赖淤,異步解耦医增。

從模型上看慎皱,MQ 模型不是狹義上的 C/S 模型,而是消息服務(wù)投遞模型:

  • 在程序角度:當(dāng)程序連接到 RabbitMQ 時必須決定自己是發(fā)送者還是接受者
  • 在 MQ 角度:MQ 及接收消息叶骨,又發(fā)送消息

AMQP(高級消息隊列協(xié)議)是對 MQ 最抽象的描述茫多。

AMQP

AMQP 定義了一個 MQ 的幾個組件,官方的描述還是比較晦澀的忽刽,我以自己的理解描述所以可能不夠準確:

  • Server(broker):MQ 服務(wù)器
  • Exchange:一個功能強大 router天揖,不做消息的存儲,單純轉(zhuǎn)發(fā)給 MQ
  • Message Queue:消息隊列跪帝,具體存儲未被消費的消息
  • Message:消息
  • Binding:關(guān)聯(lián) Exchange 和 Message Queeu 的路由表
  • Connection:鏈接今膊,TCP 鏈接
  • Channel:子鏈接,復(fù)用 Connection
  • Command:命令
  • Virtual Host:服務(wù)器創(chuàng)建的 mini 版的 MQ

Exchange & Binding

這兩個東東算是 MQ 核心功能的實現(xiàn)組件伞剑,網(wǎng)上描述的我覺得不是很清楚斑唬。

可以把 exchange 當(dāng)路由器理解,把 binding 當(dāng)路由表理解黎泣。路由器根據(jù)路由表把數(shù)據(jù)從路由器路由到一下節(jié)點恕刘,exchange 根據(jù) binding 把消息從 exchange 路由到 queue。exchange 的核心功能是路由轉(zhuǎn)發(fā)抒倚,而路由轉(zhuǎn)發(fā)的依據(jù)是 binding褐着。把 binding 當(dāng)路由表的話,那么這個路由表有三項:

  • exchange name
  • queue name
  • router key

三者的關(guān)系需要在實際生產(chǎn)托呕、消費消息之前完成綁定含蓉。而后消息到達 exchange 后根據(jù) routing key 路由到指定 queue。而 exchange 有多種不同實現(xiàn)项郊,不同實現(xiàn)的 exchange 根據(jù) routing key 的路由方式不同谴餐,適用于不同場景。

典型場景

以下例子從 Rabbit MQ 官網(wǎng)給搬運呆抑,傳送門岂嗓。

direct

direct 類型的交換器嚴格根據(jù)消息頭的 exchange name, queue name, router key 將消息路由到對應(yīng)的隊列

消息投遞到一個隊列

direct1

所有消息由默認交換器根據(jù)消息頭 queue name 投遞到隊列。沒有聲明交換器鹊碍,自動將隊列綁定到了默認交換器厌殉。下面代碼的第二個參數(shù)很容易被當(dāng)做 queue name,實際上這個字段是 routing key侈咕,發(fā)送方是不關(guān)心 queue 的公罕。

channel.queueDeclare(QUEUE_NAME, false, false, false, null);  // 聲明隊列
channel.basicPublish("",  // exchange name,空則投遞到默認交換器
                     QUEUE_NAME,  // 以 queue_name 作為 routing key
                     null, 
                     message.getBytes());

消息投遞到一個隊列由多個消費者消費

direct2

可以用于負載均衡的生產(chǎn)者消費者模型耀销,每個消息正常只被消費一次楼眷。

投遞過程與上一個一樣,隊列的消息同時由多個消費者消費

消息有選擇的分散到多個隊列

direct3
channel.exchangeDeclare(EXCHANGE_NAME, "direct");  // 聲明 direct 類型交換器
String queueName = channel.queueDeclare().getQueue();  // 聲明隨機隊列,并獲取該隊列名字
channel.queueBind(queueName, EXCHANGE_NAME, ROUTING_KEY);  // 綁定

// 發(fā)送
channel.basicPublish(EXCHANGE_NAME, 
                     ROUTING_KEY, 
                     null, 
                     message.getBytes());

完整的交換器罐柳,隊列聲明并綁定掌腰,消息根據(jù)綁定信息投遞到對應(yīng)隊列。

一個交換器與多個隊列使用相同的 routing key 進行綁定张吉,當(dāng)該 routing key 消息發(fā)送至交換器可以形成廣播的形式齿梁。

fanout

fanout
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");  // 聲明 fanout 類型交換器
String queueName = channel.queueDeclare().getQueue();  // 創(chuàng)建非持久的吊洼,唯一的闷畸,自動刪除的隊列
channel.queueBind(queueName, EXCHANGE_NAME, "");  // 綁定隊列與交換器尖淘,不要 routing key

// 發(fā)送
channel.basicPublish(EXCHANGE_NAME, 
                     "",  // routing key
                     null, 
                     message.getBytes());

交換器收到的消息廣播至所有綁定的隊列积蜻,綁定不需要給定 routing key

topic

topic
channel.exchangeDeclare(EXCHANGE_NAME, "topic");  // 聲明 topic 類型交換器
String queueName = channel.queueDeclare().getQueue();  // 創(chuàng)建非持久的、唯一的玫坛、自動刪除的隊列
channel.queueBind(queueName, EXCHANGE_NAME, ROUTING_KEY);  // 綁定隊列墩虹,交換器航厚,路由鍵

// 發(fā)送
channel.basicPublish(EXCHANGE_NAME, 
                     ROUTING_KEY, 
                     null, 
                     msg.getBytes());

編碼過程與使用 direct 交換器的完整過程一直昆码,但是 routing key 可以使用通配符:

  • * 將 . 視為分隔符進行匹配
  • #將任意字符串視為關(guān)鍵字匹配

其他

  • 消息發(fā)后即忘:消息單向傳遞气忠,默認并不會向發(fā)送方確認發(fā)送,也不會做持久化
  • prefetch count:在 direct 的第二場景下未桥,消息會被平均分配給各個消費者笔刹,而不考慮消費者的消費能力芥备《ⅲ可以使用設(shè)置 Prefetch count 保持各消費者負載均衡
  • binding key:有的文章將 bindling 中使用的 routing key 也稱作 binding key,我統(tǒng)一稱為 binding key 了
  • 相關(guān) demo 傳送門
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末萌壳,一起剝皮案震驚了整個濱河市亦镶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌袱瓮,老刑警劉巖缤骨,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異尺借,居然都是意外死亡绊起,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門燎斩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虱歪,“玉大人,你說我怎么就攤上這事栅表∷癖桑” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵怪瓶,是天一觀的道長萧落。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么找岖? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任陨倡,我火速辦了婚禮,結(jié)果婚禮上宣增,老公的妹妹穿的比我還像新娘玫膀。我一直安慰自己,他們只是感情好爹脾,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布帖旨。 她就那樣靜靜地躺著,像睡著了一般灵妨。 火紅的嫁衣襯著肌膚如雪解阅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天泌霍,我揣著相機與錄音货抄,去河邊找鬼。 笑死朱转,一個胖子當(dāng)著我的面吹牛蟹地,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播藤为,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼怪与,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缅疟?” 一聲冷哼從身側(cè)響起分别,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎存淫,沒想到半個月后耘斩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡桅咆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年括授,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岩饼。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡荚虚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忌愚,到底是詐尸還是另有隱情曲管,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布硕糊,位于F島的核電站院水,受9級特大地震影響腊徙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜檬某,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一撬腾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恢恼,春花似錦民傻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至漏隐,卻和暖如春喧半,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背青责。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工挺据, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脖隶。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓扁耐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親产阱。 傳聞我的和親對象是個殘疾皇子婉称,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)心墅,斷路器酿矢,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 來源 RabbitMQ是用Erlang實現(xiàn)的一個高并發(fā)高可靠AMQP消息隊列服務(wù)器榨乎。支持消息的持久化怎燥、事務(wù)、擁塞控...
    jiangmo閱讀 10,346評論 2 34
  • http://liuxing.info/2017/06/30/Spring%20AMQP%E4%B8%AD%E6%...
    sherlock_6981閱讀 15,889評論 2 11
  • 本文大綱 RabbitMQ 歷史 RabbitMQ 應(yīng)用場景 RabbitMQ 系統(tǒng)架構(gòu) RabbitMQ 基本概...
    Java_Explorer閱讀 16,316評論 1 40
  • 1. 歷史 RabbitMQ是一個由erlang開發(fā)的AMQP(Advanced Message Queue )的...
    高廣超閱讀 6,092評論 3 51