dedecms做地方網(wǎng)站百度推廣電話是多少
RabbitMQ的消息如何實(shí)現(xiàn)路由
-
RabbitMQ是一個(gè)基于AMQP協(xié)議實(shí)現(xiàn)的分布式消息中間件,AMQP具體的工作機(jī)制是生產(chǎn)者將消息發(fā)送到RabbitMQ Broker上的Exchange交換機(jī)上,Exchange交換機(jī)將收到的消息根據(jù)路由規(guī)則發(fā)給綁定的隊(duì)列(Queue),然后再將消息投遞給訂閱了該隊(duì)列的消費(fèi)者,從而完成消息的異步通訊
-
Exchange是一個(gè)消息交換機(jī)(消息路由規(guī)則的核心組件),可定義消息路由規(guī)則(即消息應(yīng)該路由到哪個(gè)隊(duì)列);Queue表示消息的載體,每個(gè)消息可以根據(jù)路由規(guī)則路由到一個(gè)或多個(gè)隊(duì)列中
-
Exchange負(fù)責(zé)接收生產(chǎn)者的消息,并將消息路由到消息隊(duì)列,而消息的路由規(guī)則由ExchangeType和Binding決定
-
Binding表示Queue和Exchange之間的綁定關(guān)系,每個(gè)綁定關(guān)系存在一個(gè)BindingKey,通過(guò)這種方式相當(dāng)于在Exchange中建立一個(gè)路由關(guān)系表
-
生產(chǎn)者發(fā)送消息時(shí),需要聲明一個(gè)routingKey(路由鍵),Exchange獲取到routingKey之后,根據(jù)routingKey和路由表中的BindingKey進(jìn)行匹配,而匹配的規(guī)則是通過(guò)交換機(jī)類(lèi)型ExchangeType來(lái)決定的
-
在RabbitMQ中,有三種類(lèi)型的交換機(jī):Direct 、Fanout 、Topic
1)Direct Exchange(直連交換機(jī)):具有路由功能的交換機(jī),綁定到此交換機(jī)時(shí)需要指定一個(gè)routingKey,交換機(jī)發(fā)送消息時(shí)需要routingKey,會(huì)將消息發(fā)送到對(duì)應(yīng)的隊(duì)列,即 routingKey 和 BindingKey完全一致,相當(dāng)于點(diǎn)對(duì)點(diǎn)的發(fā)送
2)Fanout Exchange(扇形交換機(jī)):廣播機(jī)制,這種方式不會(huì)基于routingKey來(lái)匹配,而是將消息廣播給綁定到當(dāng)前Exchange上的所有隊(duì)列上,速度最快,即在直連交換機(jī)的基礎(chǔ)上增加模式匹配,即對(duì)routingKey進(jìn)行模式匹配,* 代表一個(gè)單詞,# 代表多個(gè)單詞
3)Topic Exchange(主題交換機(jī)):正則表達(dá)式匹配,根據(jù)routingKey使用正則表達(dá)式進(jìn)行匹配,符合匹配規(guī)則的Queue都會(huì)收到該消息
4)首部交換機(jī)(Headers Exchange):忽略routingKey,使用Headers信息(一個(gè)Hash的數(shù)據(jù)結(jié)構(gòu))進(jìn)行匹配,優(yōu)勢(shì)在于可以有更多更靈活的匹配規(guī)則
如何保證RabbitMQ中的消息可靠傳輸
- 在RabbitMQ的整個(gè)消息傳遞過(guò)程中,有三種情況會(huì)存在消息丟失:
1)生產(chǎn)者將消息發(fā)送到RabbitMQ Server的過(guò)程中
從生產(chǎn)者發(fā)送消息的角度來(lái)說(shuō),RabbitMQ提供了一個(gè)Confirm(消息確認(rèn))機(jī)制,生產(chǎn)者發(fā)送消息到Server端以后,如果消息處理成功,Server端會(huì)返回一個(gè)ack消息??蛻舳丝梢愿鶕?jù)消息的處理結(jié)果來(lái)決定是否要做消息的重新發(fā)送,從而確保消息一定到達(dá)RabbitMQ Server上
2)RabbitMQ Server收到消息后在持久化之前宕機(jī),從而導(dǎo)致數(shù)據(jù)丟失
從RabbitMQ Server端來(lái)說(shuō),可以開(kāi)啟消息的持久化機(jī)制,即收到消息之后持久化到磁盤(pán)中
設(shè)置消息的持久化有兩個(gè)步驟: - 創(chuàng)建Queue的時(shí)候設(shè)置為持久化
- 發(fā)送消息的時(shí)候,將消息投遞模式設(shè)置為持久化投遞
即便設(shè)置了持久化消息,但是仍有可能會(huì)出現(xiàn),消息刷新到磁盤(pán)之前,RabbitMQ Server宕機(jī)導(dǎo)致消息丟失的問(wèn)題,為了確保萬(wàn)無(wú)一失,需要結(jié)合Confirm消息確認(rèn)機(jī)制一起使用
3)消費(fèi)端收到消息還沒(méi)來(lái)得及處理就宕機(jī),導(dǎo)致RabbitMQ Server認(rèn)為該消息已經(jīng)簽收
從消費(fèi)端的角度來(lái)說(shuō),我們可以將消息的自動(dòng)確認(rèn)機(jī)制修改為手動(dòng)確認(rèn),即消費(fèi)端只有手動(dòng)調(diào)用,消息確認(rèn)方法才表示消息已經(jīng)被簽收,這可能會(huì)造成重復(fù)消費(fèi)的問(wèn)題,所以這里需要考慮冪等性的設(shè)計(jì)
如:為避免MQ重復(fù)消費(fèi)導(dǎo)致數(shù)據(jù)多次被修改的問(wèn)題,可以在接受到MQ消息時(shí),將消息通過(guò)setnx命令寫(xiě)入到Redis中,一旦消息被消費(fèi)過(guò),就不會(huì)在消費(fèi)
RabbitMQ如何實(shí)現(xiàn)高可用
RabbitMQ高可用實(shí)現(xiàn)方式有兩種:
- 第一種:普通集群,在這種模式下,一個(gè)Queue的消息只會(huì)存在集群的一個(gè)節(jié)點(diǎn)上,集群中的其他節(jié)點(diǎn)會(huì)同步Queue所在節(jié)點(diǎn)的元數(shù)據(jù),消息在生產(chǎn)和消費(fèi)時(shí),不管請(qǐng)求發(fā)送到集群的哪個(gè)節(jié)點(diǎn),最終都會(huì)路由到Queue所在節(jié)點(diǎn)上去存儲(chǔ)和拉取消息,這種方式并不能保證Queue的高可用性,但可以提升RabbitMQ消息的吞吐能力
- 第二種:鏡像集群,即集群中的每個(gè)節(jié)點(diǎn)都會(huì)存儲(chǔ)Queue的數(shù)據(jù)副本,在每次生產(chǎn)消息時(shí),都需要將消息內(nèi)容同步給集群中的其他節(jié)點(diǎn),這種方式能夠保證Queue的高可用性,但集群副本之間的同步會(huì)帶來(lái)性能的損耗
另外,由于每個(gè)節(jié)點(diǎn)都保存了副本,我們還可以通過(guò)HAProxy實(shí)現(xiàn)負(fù)載均衡