接著 上篇隨筆 增加幾個(gè)概念:
成都創(chuàng)新互聯(lián)公司專注于豐滿網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供豐滿營(yíng)銷型網(wǎng)站建設(shè),豐滿網(wǎng)站制作、豐滿網(wǎng)頁(yè)設(shè)計(jì)、豐滿網(wǎng)站官網(wǎng)定制、小程序制作服務(wù),打造豐滿網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供豐滿網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。RabbitMQ是一個(gè)在AMQP(高級(jí)消息隊(duì)列協(xié)議)標(biāo)準(zhǔn)基礎(chǔ)上完整的,可服用的企業(yè)消息系統(tǒng)。
AMQP模型的功能組件圖(上圖摘自 Sophia_tj 的 第2章 AMQP模型)
AMQP的四個(gè)總要概念:1、虛擬主機(jī)(virtual host)或(vhost)
2、交換機(jī)(exchange)
3、隊(duì)列(queue)
4、綁定器(bind)
什么是虛擬主機(jī)?一組交換機(jī)、隊(duì)列和綁定器 被稱為 虛擬主機(jī)(vhost)。
為什么要用虛擬主機(jī)?RabbitMQ server 可以說就是一個(gè)消息隊(duì)列服務(wù)器實(shí)體(Broker),Broker當(dāng)中可以有多個(gè)用戶(增加用戶的命令),而用戶只能在虛擬主機(jī)的粒度進(jìn)行權(quán)限控制,所以RabbitMQ中需要多個(gè)虛擬主機(jī)。每一個(gè)RabbitMQ服務(wù)器都有一個(gè)默認(rèn)的虛擬主機(jī)“/”。
隊(duì)列(queue)是消息載體,每個(gè)消息都會(huì)被投入到一個(gè)或多個(gè)隊(duì)列。試圖創(chuàng)建一個(gè)已經(jīng)存在的隊(duì)列,RabbitMQ會(huì)直接忽略這個(gè)請(qǐng)求。(接收消息的實(shí)體)
把消息放進(jìn)隊(duì)列前,我們還需要使用另一個(gè)東西:交換機(jī)。
交換機(jī)(exchange),它指定消息按什么規(guī)則,路由到哪個(gè)隊(duì)列。它可以被理解成具有路由表的路由程序。(發(fā)送消息的實(shí)體)
交換機(jī)可以存在多個(gè),每個(gè)交換機(jī)在自己獨(dú)立的進(jìn)程當(dāng)中執(zhí)行,因此增加多個(gè)交換機(jī)就是增加多個(gè)進(jìn)程,可以充分利用服務(wù)器上的CPU核以便達(dá)到更高的效率。
交換機(jī)如何判斷要把消息送到哪個(gè)隊(duì)列?這是我們需要路由規(guī)則,也就需要綁定器了。
綁定器(bind)它的作用就是把exchange和queue按照路由規(guī)則綁定起來(lái)。(將交換器和隊(duì)列連接起來(lái),并且封裝消息的路由信息)
每個(gè)消息都有一個(gè)稱為路由關(guān)鍵字(routingKey)的屬性,exchange根據(jù)這個(gè)關(guān)鍵字進(jìn)行消息投遞,其實(shí)就是一個(gè)簡(jiǎn)單的字符串。(綁定操作就可以理解成:將exchange將具有路由關(guān)鍵字 “X” 的消息投遞到到名為“business”的隊(duì)列當(dāng)中去。)
從而一個(gè)綁定就可以概括為:一個(gè)基于路由鍵將交換機(jī)和隊(duì)列連接起來(lái)的路由規(guī)則。
需要注意:由Exchange,Queue,RoutingKey三個(gè),才能決定一個(gè)從Exchange到Queue的唯一的線路。
程序中連接與消息使用的兩個(gè)關(guān)鍵概念連接(Connection):與RabbitMQ Server建立的一個(gè)連接,由ConnectionFactory創(chuàng)建,每個(gè)connection只與一個(gè)物理的Server進(jìn)行連接,此連接是基于Socket進(jìn)行連接的。AMQP一般使用TCP。
通道 (Channel):消息通道(主要進(jìn)行相關(guān)定義,發(fā)送消息,獲取消息,事務(wù)處理等),在客戶端的每個(gè)連接里,可建立多個(gè)channel,每個(gè)channel代表一個(gè)會(huì)話任務(wù)。
Channel在.net的客戶端程序里應(yīng)該是叫“Model”,采用IModel CreateModel()創(chuàng)建的,但是其他語(yǔ)言的客戶端都叫Channel。
需要注意:一個(gè)Connection可以有多個(gè)Channel。
為什么設(shè)計(jì)中引入Channel概念?一個(gè)比較普遍的需求:客戶端程序有時(shí)候會(huì)是一個(gè)多線程程序,每一個(gè)線程都想要和RabbitMQ進(jìn)行連接,但是又不想共享一個(gè)連接。
因?yàn)橐粋€(gè)Connection就是一個(gè)TCP鏈接,RabbitMQ在設(shè)計(jì)的時(shí)候不希望與每一個(gè)客戶端保持多個(gè)TCP連接,但這確實(shí)是有些客戶端的需求,每一個(gè)Channel之間沒有任何聯(lián)系,是完全分離的。
建立在Connection基礎(chǔ)上的一個(gè)Channel,相對(duì)于Connection來(lái)說,它是輕量級(jí)的。Channel可以在多線程中使用,但是在必須保證任何時(shí)候只有一個(gè)線程執(zhí)行命令。
不得不重點(diǎn)介紹的交換機(jī)交換機(jī)定義參數(shù)type: 直接式交換機(jī)direct,topic 和 fanout。
auto_delete: 當(dāng)所有綁定隊(duì)列都不再使用時(shí),是否自動(dòng)刪除該交換機(jī)。
Fanout: 不處理路由鍵,將消息廣播給綁定到該交換機(jī)的所有隊(duì)列。 不論消息的路由關(guān)鍵字是什么,這條消息都會(huì)被路由到所有與該交換器綁定的隊(duì)列中。
廣播式交換器類型的工作方式如下:
不使用任何參數(shù)將消息隊(duì)列與交換器綁定在一起。
發(fā)布者(直接式交換器類型描述中的producer變成了publisher,已經(jīng)隱含了二種交換器類型的區(qū)別)向交換器發(fā)送一條消息。 消息被無(wú)條件的傳遞到所有和這個(gè)交換器綁定的消息隊(duì)列中。
Direct: 處理路由鍵,對(duì)消息路徑進(jìn)行全文匹配。消息路由鍵 "sunshine" 只能匹配 "sunshine" 綁定,不匹配 "sunshine.warm" 這類綁定。
通過精確匹配消息的路由關(guān)鍵字,將消息路由到零個(gè)或者多個(gè)隊(duì)列中,綁定關(guān)鍵字用來(lái)將隊(duì)列和交換器綁定到一起。這讓我們可以構(gòu)建經(jīng)典的點(diǎn)對(duì)點(diǎn)隊(duì)列消息傳輸模型,不過和任何已定義的交換器類型一樣,當(dāng)消息的路由關(guān)鍵字與多個(gè)綁定關(guān)鍵字匹配時(shí),消息可能會(huì)被發(fā)送到多個(gè)隊(duì)列中。
在direct模式下還可以實(shí)現(xiàn)多路綁定,即一個(gè)exchange和多個(gè)queue綁定時(shí),具有同樣的bindkey,如下圖:
Topic: 處理路由鍵,按模式匹配路由鍵。模式符號(hào) "#" 表示一個(gè)或多個(gè)單詞,"*" 僅匹配一個(gè)單詞。如 "wood.#" 可匹配 "wood.palm.redwood",但 "wood.*" 只匹配 "wood.deadwood"。
主題式交換器類型提供了這樣的路由機(jī)制:通過消息的路由關(guān)鍵字和綁定關(guān)鍵字的模式匹配,將消息路由到被綁定的隊(duì)列中。這種路由器類型可以被用來(lái)支持經(jīng)典的發(fā)布/訂閱消息傳輸模型——使用主題名字空間作為消息尋址模式,將消息傳遞給那些部分或者全部匹配主題模式的多個(gè)消費(fèi)者。
主題交換器類型的工作方式如下:
綁定關(guān)鍵字用零個(gè)或多個(gè)標(biāo)記構(gòu)成,每一個(gè)標(biāo)記之間用“.”字符分隔。綁定關(guān)鍵字必須用這種形式明確說明,并支持通配符:“*”匹配一個(gè)詞組,“#”零個(gè)或多個(gè)詞組。
因此綁定關(guān)鍵字“*.dask.#”匹配路由關(guān)鍵字“class.dask”和“eur.dask.tab”,但是不匹配“dask.rho”。
這種交換器類型是可選的。
主題式的原理圖解:
t