1.為什么要使用消息隊(duì)列?
1.通過(guò)異步處理提高系統(tǒng)性能;削峰、減少響應(yīng)所需時(shí)間
如果不使用消息隊(duì)列時(shí),用戶請(qǐng)求的大量數(shù)據(jù)直接寫入到數(shù)據(jù)庫(kù)中,在高并發(fā)的情況下,寫入能力驟降,響應(yīng)變慢;使用消息隊(duì)列后,用戶請(qǐng)求后可以立即加入到隊(duì)列,然后返回給用戶,數(shù)據(jù)庫(kù)通過(guò)消息隊(duì)列消費(fèi)消息,因此響應(yīng)速度能得到大幅改善。
消息隊(duì)列具有很好的削峰作用的功能——即通過(guò)異步處理,將短時(shí)間高并發(fā)產(chǎn)生的事務(wù)消息存儲(chǔ)在消息隊(duì)列中,從而削平高峰期的并發(fā)事務(wù)。
用戶請(qǐng)求數(shù)據(jù)后,由于異步操作,比如消費(fèi)消息后與數(shù)據(jù)庫(kù)的操作可能出現(xiàn)失敗的情況,這種情況我們就不能直接提示用戶操作成功,需要通過(guò)后置處理來(lái)提醒用戶成功或失敗。
2..降低系統(tǒng)耦合性
模塊之間不存在直接調(diào)用,可擴(kuò)展性更好。消費(fèi)隊(duì)列是利用發(fā)布-訂閱模式工作,生產(chǎn)者發(fā)布消息,一個(gè)或多個(gè)消費(fèi)者消費(fèi)消息,新增業(yè)務(wù)只需要訂閱消息從而實(shí)現(xiàn)網(wǎng)站業(yè)務(wù)的可擴(kuò)展性設(shè)計(jì)。
2.使用消息隊(duì)列帶來(lái)的一些問題
系統(tǒng)可用性降低:加入MQ之后,需要考慮消息丟失或者說(shuō)MQ掛掉等等的情況
系統(tǒng)復(fù)雜性提高:需要保證消息不被重復(fù)消費(fèi),處理消息丟失的情況、保證消息傳遞的順序性等等問題
一致性問題:我上面講了消息隊(duì)列可以實(shí)現(xiàn)異步,消息隊(duì)列帶來(lái)的異步確實(shí)可以提高系統(tǒng)響應(yīng)速度。但是,萬(wàn)一消息的真正消費(fèi)者并沒有正確消費(fèi)消息怎么辦?這樣就會(huì)導(dǎo)致數(shù)據(jù)不一致的情況了!
3.JMS
JMS(JAVA Message Service,Java消息服務(wù))API是一個(gè)消息服務(wù)的標(biāo)準(zhǔn)或者說(shuō)是規(guī)范。ActiveMQ 就是基于 JMS 規(guī)范實(shí)現(xiàn)的。
JMS兩種消息模型:1.點(diǎn)對(duì)點(diǎn);2.發(fā)布/訂閱
JMS 五種不同的消息正文格式:
StreamMessage -- Java原始值的數(shù)據(jù)流
MapMessage--一套名稱-值對(duì)
TextMessage--一個(gè)字符串對(duì)象
ObjectMessage--一個(gè)序列化的 Java對(duì)象
BytesMessage--一個(gè)字節(jié)的數(shù)據(jù)流
3.AMQP
AMQP,即Advanced Message Queuing Protocol,一個(gè)提供統(tǒng)一消息服務(wù)的應(yīng)用層標(biāo)準(zhǔn) 高級(jí)消息隊(duì)列協(xié)議(二進(jìn)制應(yīng)用層協(xié)議),是應(yīng)用層協(xié)議的一個(gè)開放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì),兼容 JMS。基于此協(xié)議的客戶端與消息中間件可傳遞消息,并不受客戶端/中間件同產(chǎn)品,不同的開發(fā)語(yǔ)言等條件的限制。RabbitMQ 就是基于 AMQP 協(xié)議實(shí)現(xiàn)的。
4.常見的消息隊(duì)列對(duì)比
從五個(gè)方面分析:
吞吐量:萬(wàn)級(jí)的ActiveMQ和RebbitMQ的吞吐量,要比十萬(wàn)甚至百萬(wàn)級(jí)別的RocketMQ 和 Kafka 低一個(gè)數(shù)量級(jí)
可用性:都可以實(shí)現(xiàn)高可用,ActiveMQ 和 RabbitMQ 都是基于主從架構(gòu)實(shí)現(xiàn)高可用性。RocketMQ 基于分布式架構(gòu)。 kafka 也是分布式的,一個(gè)數(shù)據(jù)多個(gè)副本,少數(shù)機(jī)器宕機(jī),不會(huì)丟失數(shù)據(jù),不會(huì)導(dǎo)致不可用
時(shí)效性:RabbitMQ 基于erlang開發(fā),所以并發(fā)能力很強(qiáng),性能極其好,延時(shí)很低,達(dá)到微秒級(jí)。其他三個(gè)都是ms 級(jí)。
功能支持:Kafka 功能較為簡(jiǎn)單,主要支持簡(jiǎn)單的MQ功能,在大數(shù)據(jù)領(lǐng)域的實(shí)時(shí)計(jì)算以及日志采集被大規(guī)模使用,其他都較為完善
消息丟失:丟失可能性很低
5.什么是 Dubbo?
Apache Dubbo (incubating) |?d?b??| 是一款高性能、輕量級(jí)的開源Java RPC 框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)。簡(jiǎn)單來(lái)說(shuō) Dubbo 是一個(gè)分布式服務(wù)框架,致力于提供高性能和透明化的RPC遠(yuǎn)程服務(wù)調(diào)用方案,以及SOA服務(wù)治理方案。
6.什么是 RPC?
RPC是遠(yuǎn)程過(guò)程調(diào)用,他是一種通過(guò)網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)請(qǐng)求服務(wù),而不需要了解網(wǎng)絡(luò)協(xié)議,比如兩臺(tái)計(jì)算機(jī),A提供一個(gè)服務(wù),B提供一個(gè)服務(wù),服務(wù)A想要調(diào)用B的服務(wù),雖然也可以通過(guò)HTTP調(diào)用實(shí)現(xiàn),但是HTTP可能會(huì)處理比較慢,并且優(yōu)化不好,用RPC就是為了解決這個(gè)問題。
7.RPC原理
1.服務(wù)消費(fèi)方調(diào)用本地方式提供的服務(wù)
2.client stub接收到調(diào)用后將調(diào)用信息組裝成網(wǎng)絡(luò)消息的傳輸體
3.client stub找到服務(wù)提供方,將消息發(fā)送
4.server stub接收到消息后進(jìn)行解碼
5.server stub根據(jù)解碼結(jié)果調(diào)用本地服務(wù)
7.將本地調(diào)用的結(jié)果打包成消息發(fā)送回client stub
8.client stub對(duì)消息進(jìn)行解密,發(fā)送給服務(wù)消費(fèi)方
9.消費(fèi)方獲得結(jié)果

8.為什么要用 Dubbo?
Dubbo的誕生與SOA分布式架構(gòu)有著密切的聯(lián)系,SOA面向服務(wù)的架構(gòu),將系統(tǒng)拆分為服務(wù)層、表現(xiàn)層兩個(gè)部分,服務(wù)層對(duì)業(yè)務(wù)邏輯進(jìn)行處理,表現(xiàn)層只需要處理與頁(yè)面的交互,業(yè)務(wù)邏輯都交給服務(wù)層進(jìn)行處理。SOA的兩個(gè)特色就是服務(wù)提供者和服務(wù)消費(fèi)者
Dubbo有四點(diǎn)特性:
1.負(fù)載均衡:可部署多臺(tái)服務(wù)器,系統(tǒng)訪問時(shí)由dubbo決定具體調(diào)用哪一臺(tái)
2.服務(wù)調(diào)用鏈路形成:部署的服務(wù)越多,服務(wù)啟動(dòng)的依賴關(guān)系就會(huì)模糊,dubbo可以解決我們服務(wù)間是如何調(diào)用的問題;
3.服務(wù)訪問壓力以及時(shí)長(zhǎng)統(tǒng)計(jì)、資源調(diào)度和治理:提供可視化工具,可以對(duì)服務(wù)進(jìn)行治理
4.服務(wù)降級(jí):如果一臺(tái)服務(wù)掛掉后,會(huì)自動(dòng)調(diào)用其他的服務(wù)。
9.什么是分布式?
分布式就是將系統(tǒng)的各個(gè)模塊通過(guò)服務(wù)的方式,部署到不同服務(wù)器上,用以減輕服務(wù)器壓力,并且可以提高系統(tǒng)并發(fā)量和性能。
10.為什么使用分布式?
1.系統(tǒng)拆分為不同的模塊便于開發(fā);
2.系統(tǒng)拆分為不同的模塊便于系統(tǒng)的維護(hù),提高系統(tǒng)的性能。
11.Dubbo的圖解

Provider: 暴露服務(wù)的服務(wù)提供方
Consumer: 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方
Registry: 服務(wù)注冊(cè)與發(fā)現(xiàn)的注冊(cè)中心
Monitor: 統(tǒng)計(jì)服務(wù)的調(diào)用次數(shù)和調(diào)用時(shí)間的監(jiān)控中心Container: 服務(wù)運(yùn)行容器
Container: 服務(wù)運(yùn)行容器
重要知識(shí)點(diǎn)總結(jié):
注冊(cè)中心負(fù)責(zé)服務(wù)地址的注冊(cè)與查找,相當(dāng)于目錄服務(wù),服務(wù)提供者和消費(fèi)者只在啟動(dòng)時(shí)與注冊(cè)中心交互,注冊(cè)中心不轉(zhuǎn)發(fā)請(qǐng)求,壓力較小
監(jiān)控中心負(fù)責(zé)統(tǒng)計(jì)各服務(wù)調(diào)用次數(shù),調(diào)用時(shí)間等,統(tǒng)計(jì)先在內(nèi)存匯總后每分鐘一次發(fā)送到監(jiān)控中心服務(wù)器,并以報(bào)表展示
注冊(cè)中心,服務(wù)提供者,服務(wù)消費(fèi)者三者之間均為長(zhǎng)連接,監(jiān)控中心除外
注冊(cè)中心通過(guò)長(zhǎng)連接感知服務(wù)提供者的存在,服務(wù)提供者宕機(jī),注冊(cè)中心將立即推送事件通知消費(fèi)者
注冊(cè)中心和監(jiān)控中心全部宕機(jī),不影響已運(yùn)行的提供者和消費(fèi)者,消費(fèi)者在本地緩存了提供者列表
注冊(cè)中心和監(jiān)控中心都是可選的,服務(wù)消費(fèi)者可以直連服務(wù)提供者
服務(wù)提供者無(wú)狀態(tài),任意一臺(tái)宕掉后,不影響使用
服務(wù)提供者全部宕掉后,服務(wù)消費(fèi)者應(yīng)用將無(wú)法使用,并無(wú)限次重連等待服務(wù)提供者恢復(fù)
12.Dubbo 提供的負(fù)載均衡策略
1.基于權(quán)重的隨機(jī)負(fù)載均衡機(jī)制;2.基于權(quán)重的輪詢負(fù)載均衡機(jī)制;3.最少活躍調(diào)用數(shù),最慢的服務(wù)活躍數(shù)計(jì)數(shù)差大;4.一致性hash
13.zookeeper宕機(jī)與dubbo直連的情況
zookeeper宕掉后,dubbo還能基于緩存在一段時(shí)間內(nèi)提供服務(wù)。dubbo的健壯性表現(xiàn)在:
1.?監(jiān)控中心宕掉不影響使用,只是丟失部分采樣數(shù)據(jù)
2. 數(shù)據(jù)庫(kù)宕掉后,注冊(cè)中心仍能通過(guò)緩存提供服務(wù)列表查詢,但不能注冊(cè)新服務(wù)
3. 注冊(cè)中心對(duì)等集群,任意一臺(tái)宕掉后,將自動(dòng)切換到另一臺(tái)
4. 注冊(cè)中心全部宕掉后,服務(wù)提供者和服務(wù)消費(fèi)者仍能通過(guò)本地緩存通訊
5. 服務(wù)提供者無(wú)狀態(tài),任意一臺(tái)宕掉后,不影響使用
6. 服務(wù)提供者全部宕掉后,服務(wù)消費(fèi)者應(yīng)用將無(wú)法使用,并無(wú)限次重連等待服務(wù)提供者恢復(fù)