1沟饥、Connection(連接rabbitmq)
rabbitmq是遵循AMQP協(xié)議的迅涮,換句話說其實rabbitmq就是erlang語言實現(xiàn)的AMQP協(xié)議的封裝废赞,AMQP說到底就是一個通訊協(xié)議,協(xié)議就一定會包含報文的交互逗柴,協(xié)議就是人為規(guī)定好的蛹头,我們只要遵從AMQP協(xié)議定義好的命令,就如同我們熟悉的http協(xié)議一樣戏溺,GET,POST等方法在AMQP中也有相應(yīng)的命令在生產(chǎn)者和消費者連接到rabbitmq的流轉(zhuǎn)過程下圖所示:
2屠尊、信道(channel)
上圖還出現(xiàn)了一個channel的名稱旷祸,我們知道其實建立連接以后其實就可以發(fā)送命令得到響應(yīng)了,那為什么會出現(xiàn)信道這個概念呢讼昆,當(dāng)建立了連接以后托享,其實就是創(chuàng)建了一個TCP連接,rabbitmq的信道就是在connection的基礎(chǔ)上建立的浸赫,每個信道都會分配唯一的標(biāo)示闰围,而AMQP的指令都是通過信道傳輸?shù)摹?p>
- 那我們思考為什么需要設(shè)計信道這個概念呢?
因為對于操作系統(tǒng)來說創(chuàng)建和銷毀連接是一個很消耗性能的操作既峡,當(dāng)遇到高峰的時候羡榴,性能會出現(xiàn)瓶頸,rabbitmq采用多路復(fù)用的方式進行管理連接运敢,信道復(fù)用了TCP連接校仑,節(jié)省了資源提高了性能忠售,到流量不大的時候,多個信道可以復(fù)用一個Connection迄沫。如圖所示:
3稻扬、生產(chǎn)者和消費者
rabbitmq是依據(jù)生產(chǎn)者消費者模型,在官方文檔中rabbitmq是這樣的介紹自己的羊瘩。
You can think about it as a post office: when you put the mail that you want posting in a post
box, you can be sure that Mr. or Ms. Mailperson will eventually deliver the mail to your
recipient. In this analogy, RabbitMQ is a post box, a post office and a postman.
- 生產(chǎn)者:生產(chǎn)者顧名思義就是消息的創(chuàng)建方泰佳,然后將創(chuàng)建好的消息發(fā)送到rabbitmq broker中;
- broker:消息中間件的服務(wù)節(jié)點尘吗,換句話說就是一個rabbitmq服務(wù)逝她;
- 消費者:消息的消費方,注意消費者只知道消費摇予,他不知道生產(chǎn)這個消息的人是誰汽绢,但是誰也不重要;
4侧戴、隊列(Queue)
rabbitmq中的一個內(nèi)置的對象宁昭,就是一條隊列,rabbitmq的消息只能存在隊列里面
消費者訂閱或者是監(jiān)聽一個隊列酗宋,就可以獲取到生產(chǎn)者發(fā)布到這個隊列的數(shù)據(jù)积仗,一個隊列可以有多個消費者,但是rabbitmq不支持廣播的操作蜕猫,多個消費者監(jiān)聽同一條隊列寂曹,隊列的消息會被平均分?jǐn)偟蕉鄠€消費者身上。
5回右、交換器隆圆,路由鍵,綁定關(guān)系(exchange,Routingkey,Binding)
交換器也是rabbitmq的一個內(nèi)置對象翔烁,生產(chǎn)者生產(chǎn)完消息不是一下子就扔到隊列中渺氧,而是先要經(jīng)過一層交換器,交換器根據(jù)消息的類型路由到一個或多條隊列中蹬屹,如果找不到目標(biāo)侣背,可能會消息丟失或者返回給生產(chǎn)者。
- 那交換器是如何路由的慨默,它是如何知道那條消息該被送到哪贩耐?
當(dāng)生產(chǎn)者發(fā)送消息的時候,會對消息進行一個標(biāo)示厦取,就是標(biāo)示消息應(yīng)該被發(fā)送到哪一條隊列潮太,rabbitmq叫這個標(biāo)示為路由鍵RoutingKey,而這個路由鍵必須和交換機類型綁定在一起才可以使用蒜胖。 - 綁定:綁定是就rabbitmq把交換器和隊列關(guān)聯(lián)起來的一種方式消别,在綁定的時候會指定一個BindingKey
- 結(jié)論:這三種概念的關(guān)系我們來捋一下抛蚤,當(dāng)生產(chǎn)者發(fā)送消息到交換器的時候需要一個Routingkey,當(dāng)bindingkey和Routingkey相同的時候就知道這個消息該送到哪個隊列了寻狂,這幾個概念確實比較繞岁经,讓人摸不得頭腦。
- 沿用rabbitmq官方文檔的比喻蛇券,把rabbitmq比喻為郵局缀壤,那交換器就是郵局門口的一個郵筒,生產(chǎn)者就是一個來寄件人纠亚,他把消息封裝在信封里塘慕,但是信封上必須寫上一些信息,這個信息就包含了地址蒂胞,這個地址就是RoutingKey图呢,比如寄到XX大學(xué),而bindingkey就是這個郵筒會到的地址骗随,如果一看這個新建信件的地址和這個郵筒的地址一致蛤织,那皆大歡喜,走你鸿染,就去了該去的地方指蚜,如果地址錯了,不好意思涨椒,丟掉或者原路返回摊鸡。其實在一定情況下這兩個玩意就是一個東西。有沒有發(fā)現(xiàn)蚕冬。都是地址嘛免猾。所以這個和交換器的類型有關(guān)。
6囤热、交換器的類型
1掸刊、fanout
此種交換器會將接收到的消息發(fā)送給所有與該交換器綁定的隊列中;
這個類型的隊列就會無視BindingKey赢乓。
2、direct
此種交換器會把消息發(fā)送到RoutingKey和BindingKey相匹配的隊列中石窑;
//定義一個direct的類型的交換器 名字叫hello
channel.exchangeDeclare("hello","direct");
//定義一條隊列牌芋,名字叫helloWorld
channel.queueDeclare("helloWorld",true,false,false,null);
//將隊列和交換機進行一個綁定
channel.queueBind("helloWorld","hello","hello");
Queue.BindOk queueBind(String queue, String exchange, String routingKey) throws IOException;
這個是java的綁定源代碼,綁定關(guān)系不是應(yīng)該使用BindingKey嗎松逊?這里使用了Routingkey
因為direct類型必須要RoutingKey和BindingKey一摸一樣才匹配躺屁,這樣就給我們了一個潛臺詞
這兩個玩意就是一個東西。
channel.basicPublish("hello","hello",MessageProperties.TEXT_PLAIN,"pujinwen".getBytes());
3经宏、topic
這是因為direct的不靈活性犀暑,因為一個全等于驯击,讓很多業(yè)務(wù)沒辦法寫,所以出來了topic耐亏,他支持一個Routingkey和bindingKey的模糊匹配徊都。支持模糊匹配符號。
4广辰、header
性能很差 ,就不介紹了暇矫,是根據(jù)發(fā)送信息的信息header內(nèi)容做匹配;
官方文檔把這個BindingKey認為是一種特殊的Routingkey择吊,所以我們都稱之為路由鍵李根,