国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
網(wǎng)易蜂巢微服務(wù)架構(gòu):用RabbitMQ實(shí)現(xiàn)輕量級(jí)通信

本次分享內(nèi)容由三個(gè)部分組成:

微服務(wù)架構(gòu)與MQ

RabbitMQ場(chǎng)景分析與優(yōu)化

RabbitMQ在網(wǎng)易蜂巢中的應(yīng)用和案例分享

1微服務(wù)架構(gòu)與MQ

微服務(wù)架構(gòu)是一種架構(gòu)模式,它將單體應(yīng)用劃分成一組微小的服務(wù),各服務(wù)之間使用輕量級(jí)的通信機(jī)制交互。

上圖左邊是單體架構(gòu)應(yīng)用,把所有業(yè)務(wù)功能放在單個(gè)進(jìn)程中,需要擴(kuò)展時(shí)以進(jìn)程為單位水平復(fù)制到多臺(tái)機(jī)器。

上圖右邊是微服務(wù)架構(gòu)應(yīng)用,將每個(gè)業(yè)務(wù)功能以獨(dú)立進(jìn)程(服務(wù))的方式部署,可以按需將微服務(wù)分別部署在多臺(tái)機(jī)器,實(shí)現(xiàn)水平擴(kuò)展。

微服務(wù)各服務(wù)之間使用“輕量級(jí)”的通信機(jī)制。所謂輕量級(jí),是指通信協(xié)議與語(yǔ)言無(wú)關(guān)、與平臺(tái)無(wú)關(guān)。

微服務(wù)通信方式:

同步:RPC,REST等

異步:消息隊(duì)列

同步通信方式

優(yōu)點(diǎn):

實(shí)現(xiàn)方便。

協(xié)議通用,比如HTTP大家都非常熟知。

系統(tǒng)架構(gòu)簡(jiǎn)單,無(wú)需中間件代理。

缺點(diǎn):

客戶端耦合服務(wù)方。

通信雙方必須同時(shí)在線,否則會(huì)造成阻塞。

客戶端需要知道服務(wù)方的Endpoint,或者需要支持服務(wù)發(fā)現(xiàn)機(jī)制。

異步通信方式

優(yōu)點(diǎn):

系統(tǒng)解耦和。

通信雙方可以互相對(duì)對(duì)方無(wú)感知。

缺點(diǎn):

額外的編程復(fù)雜性。比如需要考慮消息可靠傳輸、高性能,以及編程模型的變化等。

額外的運(yùn)維復(fù)雜性。比如消息中間件的穩(wěn)定性、高可用性、擴(kuò)展性等非功能特性。

今天的主題是消息隊(duì)列在微服務(wù)架構(gòu)中的應(yīng)用與實(shí)踐。

消息隊(duì)列中間件如何選型?主要會(huì)考慮以下幾點(diǎn):

協(xié)議:AMQP、STOMP、MQTT、私有協(xié)議等

消息是否需要持久化

吞吐量

高可用支持,是否單點(diǎn)

分布式擴(kuò)展能力

消息堆積能力和重放能力

開發(fā)便捷,易于維護(hù)

社區(qū)成熟度

選擇RabbitMQ的原因:

開源,跨平臺(tái)

靈活的消息路由策略

持久化,消息可靠傳輸

透明集群,HA支持

支持高性能高并發(fā)訪問

支持多種消息協(xié)議

豐富的客戶端、插件和平臺(tái)支持

支持RPC解決方案

2RabbitMQ場(chǎng)景分析與優(yōu)化

RabbitMQ是一個(gè)實(shí)現(xiàn)了AMQP(高級(jí)消息隊(duì)列協(xié)議)協(xié)議的消息隊(duì)列中間件。

AMQP基本模型:

1. Queue

2. Exchange: Direct, Fanout, Topic, Header

3. Binding: BindingKey, RouteKey

總結(jié):生產(chǎn)者將消息發(fā)送到Exchange,Exchange通過匹配BindingKey和消息中的RouteKey來將消息路由到隊(duì)列,最后隊(duì)列將消息投遞給消費(fèi)者。

消息可靠傳輸是業(yè)務(wù)系統(tǒng)接入MQ時(shí)首先要考慮的問題。一般消息可靠性有三個(gè)等級(jí):

At most once: 最多一次

At least once: 最少一次

Exactly once: 恰好一次

RabbitMQ支持其中的“最多一次”和“最少一次”兩種。其中“最少一次”投遞實(shí)現(xiàn)機(jī)制:

生產(chǎn)者confirm。如何開啟:使用confirm.select

消息持久化。

消費(fèi)者ack。如何開啟:使用basic.consume(…, no-ack=false)

這里說下RabbitMQ消息持久化(寫磁盤)的兩個(gè)場(chǎng)景:

顯式指定消息屬性:delivery-mode=2

內(nèi)存吃緊時(shí),消息(包括非持久化消息)轉(zhuǎn)存到磁盤,由memory_high_watermark_paging_ratio參數(shù)指定閾值。

RabbitMQ的消息持久化是通過以下機(jī)制實(shí)現(xiàn)的:

消息體寫文件

異步刷盤,合并請(qǐng)求,減少fsync系統(tǒng)調(diào)用次數(shù)

當(dāng)進(jìn)程mailbox沒有新消息時(shí),實(shí)時(shí)刷盤

confirm機(jī)制下,等f(wàn)sync系統(tǒng)調(diào)用完成后返回basic.ack確認(rèn)

RabbitMQ開啟消息可靠性參數(shù)需要注意:

unack消息在服務(wù)器端沒有超時(shí),只能等待客戶端連接斷開,重新入隊(duì)等待投遞。

消息存在重復(fù)投遞的情況,需客戶端去重:

a)基于業(yè)務(wù)層的MsgId。

b)基于RabbitMQ的Redelivered flag標(biāo)記: 不完全靠譜,仍舊可能收到重復(fù)消息。

保障性能:

a)批量publish, ack。

b)更快的磁盤(SSD,RAID等)。

c)少堆積。

消息亂序。

生產(chǎn)者confirm機(jī)制是三個(gè)可靠性參數(shù)中對(duì)性能影響最大的。一般來說有三種編程方式:

普通confirm模式。每發(fā)送一條消息后,調(diào)用waitForConfirms()方法,等待服務(wù)器端confirm。實(shí)際上是一種串行confirm。

批量confirm模式。每次發(fā)送一批消息后,調(diào)用waitForConfirms()方法,等待服務(wù)器端confirm。

異步confirm模式。注冊(cè)一個(gè)回調(diào)方法,服務(wù)器端confirm了一條(或多條)消息后SDK會(huì)回調(diào)這個(gè)方法。

下面是一些生產(chǎn)者confirm機(jī)制的專項(xiàng)性能測(cè)試數(shù)據(jù):

總結(jié):

遵循線程數(shù)越大,吞吐量越大的規(guī)律。當(dāng)線程數(shù)量達(dá)到一個(gè)閾值之后,吞吐量開始下降。

不論哪種confirm模式,通過調(diào)整客戶端線程數(shù)量,都可以達(dá)到一個(gè)最大吞吐量值。

異步和批量confirm模式兩者沒有明顯的性能差距。所以,只需從可編程性的角度選擇異步或批量或者兩者結(jié)合的模式即可。相比而言,普通confirm模式只剩編程簡(jiǎn)單這個(gè)理由了。

下面講下RabbitMQ的高可用機(jī)制。

官方提供的高可用方案:cluster + ha policy

cluster機(jī)制:多個(gè)全聯(lián)通節(jié)點(diǎn)之間元信息(exchange、queue、binding等)保持強(qiáng)一致,但是隊(duì)列消息只會(huì)存儲(chǔ)在其中一個(gè)節(jié)點(diǎn)。

優(yōu)點(diǎn):提高吞吐量,部分解決擴(kuò)展性問題。

缺點(diǎn):不能提升數(shù)據(jù)可靠性和系統(tǒng)可用性。

ha policy機(jī)制:在cluster機(jī)制基礎(chǔ)上可以指定集群內(nèi)任意數(shù)量隊(duì)列組成鏡像隊(duì)列,隊(duì)列消息會(huì)在多節(jié)點(diǎn)間復(fù)制。實(shí)現(xiàn)數(shù)據(jù)高可靠和系統(tǒng)高可用。

設(shè)置參數(shù):ha-mode和ha-params可以細(xì)粒度(哪些節(jié)點(diǎn),哪些隊(duì)列)設(shè)置鏡像隊(duì)列。

設(shè)置參數(shù):ha-sync-mode=manual(默認(rèn))/automatic可以指定集群中新節(jié)點(diǎn)的數(shù)據(jù)同步策略。

有一點(diǎn)需要注意:鏡像隊(duì)列對(duì)網(wǎng)絡(luò)抖動(dòng)非常敏感,默認(rèn)參數(shù)配置下,出現(xiàn)腦裂后RabbitMQ集群不會(huì)自我恢復(fù),需要人工介入恢復(fù),務(wù)必加好監(jiān)控和報(bào)警。

RabbitMQ流控機(jī)制 流控類型:

內(nèi)存流控:由vm_memory_high_watermark參數(shù)控制,默認(rèn)0.4

磁盤流控:由disk_free_limit參數(shù)控制,默認(rèn)50M

單條連接流控:觸發(fā)條件是下游進(jìn)程的處理速度跟不上上游進(jìn)程。

RabbitMQ內(nèi)部進(jìn)程關(guān)系調(diào)用圖

注意:當(dāng)觸發(fā)流控(全局內(nèi)存/磁盤流控,單條連接流控)時(shí),生產(chǎn)者端的publish方法會(huì)被阻塞,生產(chǎn)者需要做的是:

注冊(cè)block事件,被流控時(shí),會(huì)收到一個(gè)回調(diào)通知。

異步化處理生產(chǎn)者發(fā)送消息,不要阻塞主流程。

3RabbitMQ在網(wǎng)易蜂巢中的應(yīng)用和案例分享

網(wǎng)易蜂巢平臺(tái)的服務(wù)化架構(gòu)如下,服務(wù)間通過RabbitMQ實(shí)現(xiàn)通信:

網(wǎng)易蜂巢消息服務(wù)器設(shè)計(jì)目標(biāo):實(shí)現(xiàn)一個(gè)路由靈活、數(shù)據(jù)可靠傳輸、高可用、可擴(kuò)展的消息服務(wù)器。

設(shè)計(jì)要點(diǎn):

Exchange類型為topic。

BindingKey就是隊(duì)列名。

每個(gè)服務(wù)(圖例中的REPO/CTRL/WEB等)啟動(dòng)后會(huì)初始化一條AMQP連接,由3個(gè)channel復(fù)用:一個(gè)channel負(fù)責(zé)生產(chǎn)消息,一個(gè)channel從TYPE(REPO/CTRL/WEB等)類型的隊(duì)列消費(fèi)消息,一個(gè)channel從TYPE.${hostname}類型的隊(duì)列消費(fèi)消息。

應(yīng)用場(chǎng)景舉例:

點(diǎn)對(duì)點(diǎn)(P2P)或請(qǐng)求有狀態(tài)服務(wù):消息的RouteKey設(shè)置為TYPE.${HOSTNAME}。如host1上的WEB服務(wù)需要向host2上的REPO服務(wù)發(fā)送消息,只需將消息的RouteKey設(shè)置為REPO.host2投遞到Exchange即可。

請(qǐng)求無(wú)狀態(tài)服務(wù):如果服務(wù)提供方是無(wú)狀態(tài)服務(wù),服務(wù)調(diào)用方不關(guān)心由哪個(gè)服務(wù)進(jìn)行響應(yīng),那么只需將消息的RouteKey設(shè)置為TYPE。比如CTRL是無(wú)狀態(tài)服務(wù),host1上的WEB服務(wù)只需將消息的RouteKey設(shè)置為CTRL即可。CTRL隊(duì)列會(huì)以Round-Robin的均衡算法將消息投遞給其中的一個(gè)消費(fèi)者。

組播:如果服務(wù)調(diào)用方需要與某類服務(wù)的所有節(jié)點(diǎn)通信,可以將消息的RouteKey設(shè)置為TYPE.*,Exchange會(huì)將消息投遞到所有TYPE.${HOSTNAME}隊(duì)列。比如WEB服務(wù)需通知所有CTRL服務(wù)更新配置,只需將消息的RouteKey設(shè)置為CTRL.*。

廣播:如果服務(wù)調(diào)用方需要與所有服務(wù)的所有節(jié)點(diǎn)通信,也就是說對(duì)當(dāng)前系統(tǒng)內(nèi)所有節(jié)點(diǎn)廣播消息,可以將消息的RouteKey設(shè)置為*.*。

總結(jié):通過對(duì)RouteKey和BindingKey的精心設(shè)計(jì),可以滿足點(diǎn)對(duì)點(diǎn)(私信)、組播、廣播等業(yè)務(wù)場(chǎng)景的通信需求。

優(yōu)缺點(diǎn)分析:

優(yōu)點(diǎn):

路由策略靈活。

支持負(fù)載均衡。

支持高可用部署。

支持消息可靠傳輸(生產(chǎn)者confirm,消費(fèi)者ack,消息持久化)。

支持prefetch count,支持流控。

缺點(diǎn):

存在消息重復(fù)投遞的可能性。

超時(shí)管理,錯(cuò)誤處理等需業(yè)務(wù)層處理。

對(duì)于多服務(wù)協(xié)作的場(chǎng)景支持度有限。比如以下場(chǎng)景:WEB=> CTRL=>REPO=>CTRL=> WEB。這個(gè)時(shí)候就需要CTRL緩存WEB請(qǐng)求,直至REPO響應(yīng)。

實(shí)踐案例分享

案例一:GC引起的MQ crash

1.環(huán)境參數(shù):

11.png

2.現(xiàn)象:

RabbitMQ崩潰,產(chǎn)生的erl_crash.dump文件內(nèi)容如下:

12.png

3.直接原因:

從數(shù)據(jù)來看,虛擬機(jī)內(nèi)存共4G,Erlang虛擬機(jī)已占用約1.98G內(nèi)存(其中分配給Erlang進(jìn)程的占1.56G),此時(shí)仍向操作系統(tǒng)申請(qǐng)1.82G,因?yàn)椴僮飨到y(tǒng)本身以及其他服務(wù)也占用一些內(nèi)存,當(dāng)前系統(tǒng)已經(jīng)分不出足夠的內(nèi)存了,所以Erlang虛擬機(jī)崩潰。

4.分析:

本例有兩個(gè)不符合預(yù)期的數(shù)據(jù):
1. 內(nèi)存流控閾值控制在1.67G左右(4G*0.4),為什么崩潰時(shí)顯示占用了1.98G?
2. 為什么Erlang虛擬機(jī)會(huì)額外再申請(qǐng)1.82G內(nèi)存?

因?yàn)椋?/p>

RabbitMQ每個(gè)隊(duì)列設(shè)計(jì)為一個(gè)Erlang進(jìn)程,由于進(jìn)程GC也是采用分代策略,當(dāng)新老生代一起參與Major GC時(shí),Erlang虛擬機(jī)會(huì)新開內(nèi)存,根據(jù)root set將存活的對(duì)象拷貝至新空間,這個(gè)過程會(huì)造成新老內(nèi)存空間同時(shí)存在,極端情況下,一個(gè)隊(duì)列可能短期內(nèi)需要兩倍的內(nèi)存占用量。這就是RabbitMQ將內(nèi)存流控的安全閾值默認(rèn)設(shè)置為0.4的原因。

內(nèi)存流控參數(shù)vm_memory_high_watermark 為0.4的意思是,當(dāng)RabbitMQ的內(nèi)存使用量大于40%時(shí),開始進(jìn)行生產(chǎn)者流控,但是該參數(shù)并不承諾RabbitMQ的內(nèi)存使用率不大于40%。

5.如何解決(規(guī)避)?

RabbitMQ獨(dú)立部署,不與其他Server共享內(nèi)存資源。

進(jìn)一步降低vm_memory_high_watermark值,比如設(shè)置成0.3,但是這種方式會(huì)造成內(nèi)存資源利用率太低。

升級(jí)RabbitMQ至新版(3.4+),新版RabbitMQ對(duì)內(nèi)存管理有過改進(jìn)。

案例二:鏡像隊(duì)列的單節(jié)點(diǎn)磁盤故障造成消息丟失

1.環(huán)境參數(shù):RabbitMQ: 3.1.5 (ha policy, ha-mode:all)

2.現(xiàn)象:

a)節(jié)點(diǎn)A的數(shù)據(jù)盤故障(磁盤控制器故障、無(wú)法讀寫),所有原本A上的生產(chǎn)者消費(fèi)者failover到B節(jié)點(diǎn)。

b)從節(jié)點(diǎn)B的WebUI上看,所有隊(duì)列信息(包括隊(duì)列元信息和數(shù)據(jù))丟失,但是exchange、binding、vhost等依舊存在。

c)節(jié)點(diǎn)B的日志中出現(xiàn)大量關(guān)于消費(fèi)請(qǐng)求的錯(cuò)誤日志:

13.png

d)從生產(chǎn)者端看來一切正常,依舊會(huì)收到來自節(jié)點(diǎn)B的confirm消息(basic.ack amqp方法)。

3.分析:

上述現(xiàn)象實(shí)際上有兩個(gè)坑在里面:

在數(shù)據(jù)可靠傳輸方面,鏡像隊(duì)列也不完全可靠。這是一個(gè)Bug。RabbitMQ 3.5.1版本以下都存在這個(gè)問題。

要保證消息可靠性,生產(chǎn)者端僅僅采用confirm機(jī)制還不夠。對(duì)于那些路由不可達(dá)的消息(根據(jù)RouteKey匹配不到相應(yīng)隊(duì)列),RabbitMQ會(huì)直接丟棄消息,同時(shí)confirm客戶端。

4.如何解決(規(guī)避)?

升級(jí)RabbitMQ到新版,至少3.5.1及以上。

生產(chǎn)者basic.publish方法設(shè)置mandatory參數(shù),它的作用是:對(duì)于那些路由不可達(dá)的消息,RabbitMQ會(huì)先通過basic.return消息向生產(chǎn)者返回消息內(nèi)容,然后再發(fā)送basic.ack消息進(jìn)行確認(rèn)

Q & A

Q1:為保障消息隊(duì)列穩(wěn)定性,消息隊(duì)列監(jiān)控點(diǎn)主要有哪些?

A1:首先是服務(wù)器的基礎(chǔ)監(jiān)控是要的。CPU,內(nèi)存,磁盤IO都是敏感項(xiàng)。特別是內(nèi)存,報(bào)警閾值可能要設(shè)置在50%以下,原因前面也說過,極端情況下一個(gè)隊(duì)列的內(nèi)存占用量可能是兩倍當(dāng)前值。

然后MQ業(yè)務(wù)的監(jiān)控也需要加,比如消息堆積數(shù),unack的消息數(shù),連接數(shù),channel數(shù)等等。RabbitMQ有提供rest api可以拿到這些監(jiān)控。

還有因?yàn)镽abbitMQ對(duì)網(wǎng)絡(luò)分區(qū)非常敏感,所以日志監(jiān)控也要加。RabbitMQ出現(xiàn)網(wǎng)絡(luò)分區(qū)或者觸發(fā)流控都會(huì)在它的運(yùn)行日志中有輸出。

大致就是這么幾點(diǎn)。

Q2:rabbitmq有嘗試結(jié)合netty提高網(wǎng)絡(luò)處理能力?

A2:erlang是actor模型代表,我覺得它的網(wǎng)絡(luò)處理能力也不比netty差的。

  

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
消息隊(duì)列RabbitMQ和ActiveMQ的生產(chǎn)者流量控制
RabbitMQ中 exchange、route、queue的關(guān)系
RabbitMQ三種Exchange模式(fanout,direct,topic)的性能比較 | V...
如何保證消息隊(duì)列的可靠性傳輸?
萬(wàn)字長(zhǎng)文書寫RabbitMQ最全見解!以后再也不用到處去搜索了呀!
消息隊(duì)列技術(shù)選型:5種主流消息隊(duì)列,哪個(gè)最香?
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服