日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
分布式消息隊(duì)列:順序消息的基礎(chǔ)邏輯

分布式消息隊(duì)列是分布式系統(tǒng)架構(gòu)中的關(guān)鍵組件,主要用于解決應(yīng)用耦合、異步消息、流量削峰的問(wèn)題。隨著業(yè)務(wù)邏輯的拆分和業(yè)務(wù)系統(tǒng)的微服務(wù)改造,不僅要求消息隊(duì)列在性能和可靠性上有充分保障,也對(duì)其在一些特殊業(yè)務(wù)場(chǎng)景的功能支持上提出了需求。本文就分布式消息隊(duì)列順序消息的基礎(chǔ)邏輯及使用過(guò)程中的問(wèn)題進(jìn)行了簡(jiǎn)單總結(jié)。

分布式消息隊(duì)列的消息順序問(wèn)題

在分布式架構(gòu)中,消息隊(duì)列為實(shí)現(xiàn)其高性能、高可用以及彈性伸縮等特點(diǎn),其存儲(chǔ)數(shù)據(jù)的邏輯結(jié)構(gòu)大都選擇了多分區(qū)的模式,即將一個(gè)Topic劃分為多個(gè)Partition。多分區(qū)的設(shè)計(jì)大幅提高了架構(gòu)的并發(fā)性和可用性,但消息隊(duì)列本身僅能保證每個(gè)Partition內(nèi)部消息的有序性,整個(gè)Topic內(nèi)、多個(gè)Partition之間消息的順序性無(wú)法得到保障。

圖1 普通消息的收發(fā)樣例

在圖1中,a1-a4四條按順序生產(chǎn)的消息在消費(fèi)的時(shí)候已經(jīng)被徹底打亂,在一般的業(yè)務(wù)場(chǎng)景中該消費(fèi)結(jié)果是可接受的,但在部分有特殊需求的場(chǎng)景中則不能滿足業(yè)務(wù)需求。如在給用戶發(fā)送銀行卡余額變更的場(chǎng)景中,必須保證同一賬戶的余額變更通知是順序的,對(duì)于業(yè)務(wù)端順序生成的余額變更消息a1,a2,a3,a4,必須保證用戶接收消息的順序也是a1,a2,a3,a4,如圖2所示。

圖2 順序消息的業(yè)務(wù)需求

在此類有順序需求的場(chǎng)景里,就需要業(yè)務(wù)系統(tǒng)端和消息隊(duì)列服務(wù)端“共同努力”,保障業(yè)務(wù)邏輯的實(shí)現(xiàn)。

順序消息的基礎(chǔ)實(shí)現(xiàn)邏輯

順序消息是指生產(chǎn)者將需要保證順序的一批消息嚴(yán)格按照先進(jìn)先出(FIFO)的原則發(fā)送到消息隊(duì)列中,在消費(fèi)的時(shí)候消費(fèi)者對(duì)這一批消息按相同的先后順序進(jìn)行消費(fèi)。根據(jù)業(yè)務(wù)場(chǎng)景,一般將順序消息劃分為局部順序和全局順序兩種,但全局順序是局部順序的一種特殊實(shí)現(xiàn),因此本文后續(xù)的討論中均圍繞局部順序展開(kāi)。

局部順序:對(duì)于指定的一個(gè)Topic,只需要保證具有相同標(biāo)識(shí)的一批消息嚴(yán)格按照先進(jìn)先出的原則進(jìn)行發(fā)布和消費(fèi)即可,不同標(biāo)識(shí)的消息之間不做順序要求,上文中提到的在給用戶發(fā)送余額變更短信的場(chǎng)景中,只需要保證相同賬戶ID的通知消息具有順序性即可,不同賬戶之間的短信通知順序無(wú)需保證。在實(shí)現(xiàn)上,大部分消息隊(duì)列都是通過(guò)在投放時(shí)對(duì)Message設(shè)置ShardingKey,將具有相同ShardingKey的Message投放到相同的Partition的方式保障消息順序存儲(chǔ),如圖3所示。

圖3 通過(guò)ShardingKey實(shí)現(xiàn)局部順序

全局順序:對(duì)于指定的一個(gè)Topic,所有消息按照嚴(yán)格的先入先出(FIFO)的順序來(lái)發(fā)布和消費(fèi)。全局順序消息實(shí)際上是一種特殊的局部順序消息,或者是將該Topic所有的消息打上相同的ShardingKey實(shí)現(xiàn),或者是在消息隊(duì)列服務(wù)端只為該Topic提供1個(gè)Partition,因此其并發(fā)度和性能都將嚴(yán)重受損。

分區(qū)變動(dòng)帶來(lái)的順序錯(cuò)亂

在正常場(chǎng)景下,通過(guò)ShardingKey的方式可以保證消息的有序性,但分布式隊(duì)列在使用過(guò)程中經(jīng)常會(huì)遇到分區(qū)故障或分區(qū)擴(kuò)縮容的情況,此時(shí)很難保障消息的嚴(yán)格順序。

如在Rocket MQ的主從架構(gòu)中,主Broker的故障必然會(huì)帶來(lái)分區(qū)數(shù)量的變化,此時(shí)通過(guò)ShardingKey計(jì)算出的分區(qū)ID也將變化,從而導(dǎo)致消息順序的錯(cuò)亂。

圖4 Partition故障導(dǎo)致消息順序錯(cuò)亂

如圖4所示,正常場(chǎng)景下a1,a2投遞到Partition2,此時(shí)Partition3發(fā)生故障,消息隊(duì)列服務(wù)端的Partition數(shù)量發(fā)生變化,同一ShardingKey的Hash算法結(jié)果會(huì)出現(xiàn)變動(dòng),因此a3、a4兩條消息被投遞到Partition1,此時(shí)兩個(gè)隊(duì)列之間的消費(fèi)順序無(wú)法得到保障。

在Kafka的架構(gòu)設(shè)計(jì)中,盡管Partition副本會(huì)在Leader故障后重新選主,故障前后分區(qū)的數(shù)量未發(fā)生變化,但要注意分區(qū)選主的過(guò)程中整個(gè)Partition處于不可用的狀態(tài),此時(shí)如果有順序消息生成也將導(dǎo)致順序錯(cuò)亂。

實(shí)踐場(chǎng)景中必須注意的兩個(gè)問(wèn)題

概括來(lái)說(shuō),順序消息的實(shí)現(xiàn)只需要Producer給Message打上ShardingKey即可,但在實(shí)際使用過(guò)程中仍然需要在使用時(shí)結(jié)合不同消息隊(duì)列產(chǎn)品的特性做針對(duì)性的優(yōu)化,下面針對(duì)Kafka和RocketMQ兩款產(chǎn)品順序消息的使用過(guò)程中需要注意的問(wèn)題做簡(jiǎn)單介紹。

1. 同步發(fā)送保障消息投遞的有序

要保證消息在發(fā)送階段的有序性,就要在同一個(gè)Producer線程中,使用同步發(fā)送的方法對(duì)消息進(jìn)行發(fā)送,同時(shí)要注意對(duì)于發(fā)送失敗的情況下要在Producer端做好重試控制,避免因投遞失敗帶來(lái)的順序錯(cuò)誤。

在RocketMQ中,Producer提供的send()方法默認(rèn)為同步發(fā)送,應(yīng)用可以根據(jù)返回的SendResult判斷當(dāng)前消息是否投遞成功。但在Kafka中,所有的發(fā)送本質(zhì)上都是異步發(fā)送,用戶編碼的Producer線程調(diào)用的send()方法僅是將消息暫存到客戶端本地的RecordAccumulator中,實(shí)際將消息從本地發(fā)送到Broker的是后臺(tái)的Kafka Sender線程。

圖5 Kafka發(fā)送消息的實(shí)際邏輯

因此在Kafka中,要實(shí)現(xiàn)同步發(fā)送的效果要首先獲取send()方法返回的Future對(duì)象,而后調(diào)用Future對(duì)象的get()方法進(jìn)行阻塞,等待Kafka Broker的響應(yīng)。

2. 多worker線程消費(fèi)的問(wèn)題

在分布式消息隊(duì)列的消費(fèi)模型中,為了保障同一Partition內(nèi)消息的順序消費(fèi),一個(gè)Partition在同一個(gè)消費(fèi)組中只能被一個(gè)consumer實(shí)例消費(fèi),因此該消費(fèi)組的消費(fèi)能力與Partition的數(shù)量密切相關(guān),為解決這一問(wèn)題很多應(yīng)用在消費(fèi)時(shí)將consumer僅作為拉取消息的實(shí)例,在內(nèi)部實(shí)現(xiàn)多worker線程提高并發(fā)度,此時(shí)盡管consumer實(shí)例拉取到的消息是有序的,但消息在不同的worker線程中處理,也會(huì)出現(xiàn)順序錯(cuò)亂的問(wèn)題。 

圖6 多worker線程消費(fèi)導(dǎo)致消息順序錯(cuò)亂

要保障消息的消費(fèi)順序,必須保障同一ShardingKey的消息在同一線程中處理??蛻舳嗽谙M(fèi)時(shí)采用了多worker的邏輯,可以為每一個(gè)worker線程引入一個(gè)阻塞隊(duì)列,consumer分發(fā)消息時(shí)將相同ShardingKey的消息放入同一個(gè)阻塞隊(duì)列消費(fèi),worker線程不斷輪詢從阻塞隊(duì)列中獲取消息處理即可。

總結(jié)

在系統(tǒng)的微服務(wù)改造過(guò)程中,順序消息的使用是不可避免的,用戶要對(duì)消息隊(duì)列的實(shí)現(xiàn)邏輯有清晰的認(rèn)識(shí),并對(duì)其在故障場(chǎng)景下可能造成的影響有提前的預(yù)估。本文對(duì)順序消息的基礎(chǔ)實(shí)現(xiàn)邏輯、服務(wù)端故障導(dǎo)致的消息順序錯(cuò)亂以及應(yīng)用設(shè)計(jì)在producer端和consumer端需要注意的問(wèn)題進(jìn)行了總結(jié)性說(shuō)明,應(yīng)當(dāng)充分認(rèn)識(shí)到順序消息相關(guān)業(yè)務(wù)場(chǎng)景的實(shí)現(xiàn)不能僅僅靠消息隊(duì)列本身去保障,需要業(yè)務(wù)端一起共同努力去實(shí)現(xiàn)。


分享題目:分布式消息隊(duì)列:順序消息的基礎(chǔ)邏輯
標(biāo)題路徑:http://m.5511xx.com/article/djehsdc.html