前言
現(xiàn)今時(shí)代,系統(tǒng)越來(lái)越復(fù)雜,數(shù)據(jù)來(lái)越多,系統(tǒng)間的交互也就變得越來(lái)越重要,同時(shí)也變得越來(lái)越困難。而消息中間件在其中起到了一個(gè)中間橋梁的重要作用。因此,面試中也經(jīng)常會(huì)被問(wèn)到消息中間件相關(guān)的問(wèn)題。從其使用到其原理設(shè)計(jì),都會(huì)是面試官感興趣的一個(gè)點(diǎn)。
小編分享的這份Java后端開(kāi)發(fā)面試總結(jié)包含了JavaOOP、Java集合容器、Java異常、并發(fā)編程、Java反射、Java序列化、JVM、Redis、Spring MVC、MyBatis、MySQL數(shù)據(jù)庫(kù)、消息中間件MQ、Dubbo、Linux、ZooKeeper、 分布式&數(shù)據(jù)結(jié)構(gòu)與算法等26個(gè)專題技術(shù)點(diǎn),都是小編在各個(gè)大廠總結(jié)出來(lái)的面試真題,已經(jīng)有很多粉絲靠這份PDF拿下眾多大廠的offer,今天在這里總結(jié)分享給到大家!【已完結(jié)】
備戰(zhàn)秋招、查漏補(bǔ)缺:Java后端面試最全攻略
Zookeeper
1. ZooKeeper 是什么?
ZooKeeper 是一個(gè)開(kāi)放源碼的分布式協(xié)調(diào)服務(wù),它是集群的管理者,監(jiān)視著集群中各個(gè)節(jié)點(diǎn)的狀態(tài)根 據(jù)節(jié)點(diǎn)提交的反饋進(jìn)行下一步合理操作。最終,將簡(jiǎn)單易用的接口和性能高效、功能穩(wěn)定的系統(tǒng)提供給用戶。
分布式應(yīng)用程序可以基于 Zookeeper 實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖和分布式隊(duì)列等功能。
Zookeeper 保證了如下分布式一致性特性:
(1)順序一致性
(2)原子性
(3)單一視圖
(4)可靠性
(5)實(shí)時(shí)性(最終一致性)
客戶端的讀請(qǐng)求可以被集群中的任意一臺(tái)機(jī)器處理,如果讀請(qǐng)求在節(jié)點(diǎn)上注冊(cè)了監(jiān)聽(tīng)器,這個(gè)監(jiān)聽(tīng)器也 是由所連接的 zookeeper 機(jī)器來(lái)處理。對(duì)于寫請(qǐng)求,這些請(qǐng)求會(huì)同時(shí)發(fā)給其他 zookeeper 機(jī)器并且達(dá)成一致后,請(qǐng)求才會(huì)返回成功。因此,隨著 zookeeper 的集群機(jī)器增多,讀請(qǐng)求的吞吐會(huì)提高但是寫 請(qǐng)求的吞吐會(huì)下降。
有序性是 zookeeper 中非常重要的一個(gè)特性,所有的更新都是全局有序的,每個(gè)更新都有一個(gè)唯一的時(shí)間戳,這個(gè)時(shí)間戳稱為 zxid(Zookeeper Transaction Id)。而讀請(qǐng)求只會(huì)相對(duì)于更新有序,也就是 讀請(qǐng)求的返回結(jié)果中會(huì)帶有這個(gè)zookeeper 最新的 zxid。
2. ZooKeeper 提供了什么?
(1)文件系統(tǒng)
(2)通知機(jī)制
3.Zookeeper 文件系統(tǒng)
Zookeeper 提供一個(gè)多層級(jí)的節(jié)點(diǎn)命名空間(節(jié)點(diǎn)稱為 znode)。與文件系統(tǒng)不同的是,這些節(jié)點(diǎn)都可以設(shè)置關(guān)聯(lián)的數(shù)據(jù),而文件系統(tǒng)中只有文件節(jié)點(diǎn)可以存放數(shù)據(jù)而目錄節(jié)點(diǎn)不行。 Zookeeper 為了保證高吞吐和低延遲,在內(nèi)存中維護(hù)了這個(gè)樹(shù)狀的目錄結(jié)構(gòu),這種特性使得Zookeeper 不能用于存放大量的數(shù)據(jù),每個(gè)節(jié)點(diǎn)的存放數(shù)據(jù)上限為1M。
4. ZAB 協(xié)議?
ZAB 協(xié)議是為分布式協(xié)調(diào)服務(wù) Zookeeper 專門設(shè)計(jì)的一種支持崩潰恢復(fù)的原子廣播協(xié)議。 ZAB 協(xié)議包括兩種基本的模式:崩潰恢復(fù)和消息廣播。 當(dāng)整個(gè) zookeeper 集群剛剛啟動(dòng)或者 Leader 服務(wù)器宕機(jī)、重啟或者網(wǎng)絡(luò)故障導(dǎo)致不存在過(guò)半的服務(wù)器 與 Leader 服務(wù)器保持正常通信時(shí),所有進(jìn)程(服務(wù)器)進(jìn)入崩潰恢復(fù)模式,首先選舉產(chǎn)生新的 Leader服務(wù)器,然后集群中 Follower 服務(wù)器開(kāi)始與新的 Leader 服務(wù)器進(jìn)行數(shù)據(jù)同步,當(dāng)集群中超過(guò)半數(shù)機(jī)器與該 Leader服務(wù)器完成數(shù)據(jù)同步之后,退出恢復(fù)模式進(jìn)入消息廣播模式,Leader 服務(wù)器開(kāi)始接收客戶端的事務(wù)請(qǐng)求生成事物提案來(lái)進(jìn)行事務(wù)請(qǐng)求處理。
5. 四種類型的數(shù)據(jù)節(jié)點(diǎn) Znode
(1)PERSISTENT-持久節(jié)點(diǎn)
除非手動(dòng)刪除,否則節(jié)點(diǎn)一直存在于 Zookeeper 上
(2)EPHEMERAL-臨時(shí)節(jié)點(diǎn)
臨時(shí)節(jié)點(diǎn)的生命周期與客戶端會(huì)話綁定,一旦客戶端會(huì)話失效(客戶端與zookeeper 連接斷開(kāi)不一定會(huì)話失效),那么這個(gè)客戶端創(chuàng)建的所有臨時(shí)節(jié)點(diǎn)都會(huì)被移除。
(3)PERSISTENT_SEQUENTIAL-持久順序節(jié)點(diǎn)
基本特性同持久節(jié)點(diǎn),只是增加了順序?qū)傩?,?jié)點(diǎn)名后邊會(huì)追加一個(gè)由父節(jié)點(diǎn)維護(hù)的自增整型數(shù)字。
(4)EPHEMERAL_SEQUENTIAL-臨時(shí)順序節(jié)點(diǎn)
基本特性同臨時(shí)節(jié)點(diǎn),增加了順序?qū)傩裕?jié)點(diǎn)名后邊會(huì)追加一個(gè)由父節(jié)點(diǎn)維護(hù)的自增整型數(shù)字。
6. Zookeeper Watcher 機(jī)制 -- 數(shù)據(jù)變更通知
Zookeeper 允許客戶端向服務(wù)端的某個(gè) Znode 注冊(cè)一個(gè) Watcher 監(jiān)聽(tīng),當(dāng)服務(wù)端的一些指定事件觸發(fā)了這個(gè) Watcher,服務(wù)端會(huì)向指定客戶端發(fā)送一個(gè)事件通知來(lái)實(shí)現(xiàn)分布式的通知功能,然后客戶端根據(jù)Watcher 通知狀態(tài)和事件類型做出業(yè)務(wù)上的改變。
工作機(jī)制:
(1)客戶端注冊(cè) watcher
(2)服務(wù)端處理 watcher
(3)客戶端回調(diào) watcher
Watcher 特性總結(jié):
(1)一次性無(wú)論是服務(wù)端還是客戶端,一旦一個(gè) Watcher 被 觸 發(fā) ,Zookeeper 都會(huì)將其從相應(yīng)的存儲(chǔ)中移除。這樣的設(shè)計(jì)有效的減輕了服務(wù)端的壓力,不然對(duì)于更新非常頻繁的節(jié)點(diǎn),服務(wù)端會(huì)不斷的向客戶端發(fā)送事件通知,無(wú)論對(duì)于網(wǎng)絡(luò)還是服務(wù)端的壓力都非常大。
(2)客戶端串行執(zhí)行
客戶端 Watcher 回調(diào)的過(guò)程是一個(gè)串行同步的過(guò)程。
(3)輕量
3.1、Watcher 通知非常簡(jiǎn)單,只會(huì)告訴客戶端發(fā)生了事件,而不會(huì)說(shuō)明事件的具體內(nèi)容。
3.2、客戶端向服務(wù)端注冊(cè) Watcher 的時(shí)候,并不會(huì)把客戶端真實(shí)的 Watcher 對(duì)象實(shí)體傳遞到服務(wù)端,僅僅是在客戶端請(qǐng)求中使用 boolean 類型屬性進(jìn)行了標(biāo)記。
(4)watcher event 異步發(fā)送 watcher 的通知事件從 server 發(fā)送到 client 是異步的,這就存在一個(gè)問(wèn)題,不同的客戶端和服務(wù)器之間通過(guò) socket 進(jìn)行通信,由于網(wǎng)絡(luò)延遲或其他因素導(dǎo)致客戶端在不通的時(shí)刻監(jiān)聽(tīng)到事件,由于 Zookeeper 本身提供了 ordering guarantee,即客戶端監(jiān)聽(tīng)事件后,才會(huì)感知它所監(jiān)視 znode發(fā)生了變化。所以我們使用 Zookeeper 不能期望能夠監(jiān)控到節(jié)點(diǎn)每次的變化。Zookeeper 只能保證最終的一致性,而無(wú)法保證強(qiáng)一致性。
(5)注冊(cè) watcher getData、exists、getChildren
(6)觸發(fā) watcher create、delete、setData
(7)當(dāng)一個(gè)客戶端連接到一個(gè)新的服務(wù)器上時(shí),watch 將會(huì)被以任意會(huì)話事件觸發(fā)。當(dāng)與一個(gè)服務(wù)器失去連接的時(shí)候,是無(wú)法接收到 watch 的。而當(dāng) client 重新連接時(shí),如果需要的話,所有先前注冊(cè)過(guò)的 watch,都會(huì)被重新注冊(cè)。通常這是完全透明的。只有在一個(gè)特殊情況下,watch 可能會(huì)丟失:對(duì)于一個(gè)未創(chuàng)建的 znode的 exist watch,如果在客戶端斷開(kāi)連接期間被創(chuàng)建了,并且隨后在客戶端連接上之前又刪除了,這種情況下,這個(gè) watch 事件可能會(huì)被丟失。
7. 客戶端注冊(cè) Watcher 實(shí)現(xiàn)
(1)調(diào)用 getData()/getChildren()/exist()三個(gè) API,傳入 Watcher 對(duì)象
(2)標(biāo)記請(qǐng)求 request,封裝 Watcher 到 WatchRegistration
(3)封裝成 Packet 對(duì)象,發(fā)服務(wù)端發(fā)送 request
(4)收到服務(wù)端響應(yīng)后,將 Watcher 注冊(cè)到 ZKWatcherManager 中進(jìn)行管理
(5)請(qǐng)求返回,完成注冊(cè)。
8. 服務(wù)端處理 Watcher 實(shí)現(xiàn)
9. 客戶端回調(diào) Watcher
- 客戶端 SendThread 線程接收事件通知,交由 EventThread 線程回調(diào) Watcher。
- 客戶端的 Watcher 機(jī)制同樣是一次性的,一旦被觸發(fā)后,該 Watcher 就失效了。
10. ACL 權(quán)限控制機(jī)制
11. Chroot 特性

12. 會(huì)話管理
13. 服務(wù)器角色
14. Zookeeper 下 Server 工作狀態(tài)
服務(wù)器具有四種狀態(tài),分別是 LOOKING、FOLLOWING、LEADING、OBSERVING。
(1)LOOKING:尋 找 Leader 狀態(tài)。當(dāng)服務(wù)器處于該狀態(tài)時(shí),它會(huì)認(rèn)為當(dāng)前集群中沒(méi)有 Leader,因此需要進(jìn)入 Leader 選舉狀態(tài)。
(2)FOLLOWING:跟隨者狀態(tài)。表明當(dāng)前服務(wù)器角色是 Follower。
(3)LEADING:領(lǐng)導(dǎo)者狀態(tài)。表明當(dāng)前服務(wù)器角色是 Leader。
(4)OBSERVING:觀察者狀態(tài)。表明當(dāng)前服務(wù)器角色是 Observer。
15. 數(shù)據(jù)同步
16. zookeeper 是如何保證事務(wù)的順序一致性的?

17. 分布式集群中為什么會(huì)有 Master?
在分布式環(huán)境中,有些業(yè)務(wù)邏輯只需要集群中的某一臺(tái)機(jī)器進(jìn)行執(zhí)行,其他的機(jī)器可以共享這個(gè)結(jié)果,這樣可以大大減少重復(fù)計(jì)算,提高性能,于是就需要進(jìn)行l(wèi)eader 選舉。
18. zk 節(jié)點(diǎn)宕機(jī)如何處理?
19. zookeeper 負(fù)載均衡和 nginx 負(fù)載均衡區(qū)別
zk 的負(fù)載均衡是可以調(diào)控,nginx 只是能調(diào)權(quán)重,其他需要可控的都需要自己寫插件;但是 nginx 的吞吐量比 zk 大很多,應(yīng)該說(shuō)按業(yè)務(wù)選擇用哪種方式。
20. Zookeeper 有哪幾種幾種部署模式?
部署模式:?jiǎn)螜C(jī)模式、偽集群模式、集群模式
21. 集群最少要幾臺(tái)機(jī)器,集群規(guī)則是怎樣的?
集群規(guī)則為 2N+1 臺(tái),N>0,即 3 臺(tái)
22. 集群支持動(dòng)態(tài)添加機(jī)器嗎?

23. Zookeeper 對(duì)節(jié)點(diǎn)的 watch 監(jiān)聽(tīng)通知是永久的嗎?為什么不是永久的?

24. Zookeeper 的 java 客戶端都有哪些?
java 客戶端:zk 自帶的 zkclient 及 Apache 開(kāi)源的 Curator。
25. chubby 是什么,和 zookeeper 比你怎么看?
chubby 是 google 的,完全實(shí)現(xiàn) paxos 算法,不開(kāi)源。zookeeper 是 chubby的開(kāi)源實(shí)現(xiàn),使用 zab協(xié)議,paxos 算法的變種。
26. 說(shuō)幾個(gè) zookeeper 常用的命令。
常用命令:ls get set create delete 等。
27. ZAB 和 Paxos 算法的聯(lián)系與區(qū)別?
28. Zookeeper 的典型應(yīng)用場(chǎng)景
Zookeeper 是一個(gè)典型的發(fā)布/訂閱模式的分布式數(shù)據(jù)管理與協(xié)調(diào)框架,開(kāi)發(fā)人員可以使用它來(lái)進(jìn)行分布式數(shù)據(jù)的發(fā)布和訂閱。
通過(guò)對(duì) Zookeeper 中豐富的數(shù)據(jù)節(jié)點(diǎn)進(jìn)行交叉使用,配合 Watcher 事件通知機(jī)制,可以非常方便的構(gòu)建一系列分布式應(yīng)用中年都會(huì)涉及的核心功能,如:
- (1)數(shù)據(jù)發(fā)布/訂閱
- (2)負(fù)載均衡
- (3)命名服務(wù)
- (4)分布式協(xié)調(diào)/通知
- (5)集群管理(6)Master 選舉
- (7)分布式鎖
- (8)分布式隊(duì)列
數(shù)據(jù)發(fā)布/訂閱
介紹
數(shù)據(jù)發(fā)布/訂閱系統(tǒng),即所謂的配置中心,顧名思義就是發(fā)布者發(fā)布數(shù)據(jù)供訂閱者進(jìn)行數(shù)據(jù)訂閱。
目的
動(dòng)態(tài)獲取數(shù)據(jù)(配置信息)
實(shí)現(xiàn)數(shù)據(jù)(配置信息)的集中式管理和數(shù)據(jù)的動(dòng)態(tài)更新
設(shè)計(jì)模式
Push 模式
Pull 模式
數(shù)據(jù)(配置信息)特性
(1)數(shù)據(jù)量通常比較小
(2)數(shù)據(jù)內(nèi)容在運(yùn)行時(shí)會(huì)發(fā)生動(dòng)態(tài)更新
(3)集群中各機(jī)器共享,配置一致
如:機(jī)器列表信息、運(yùn)行時(shí)開(kāi)關(guān)配置、數(shù)據(jù)庫(kù)配置信息等
基于 Zookeeper 的實(shí)現(xiàn)方式
· 數(shù)據(jù)存儲(chǔ):將數(shù)據(jù)(配置信息)存儲(chǔ)到 Zookeeper 上的一個(gè)數(shù)據(jù)節(jié)點(diǎn)
· 數(shù)據(jù)獲?。簯?yīng)用在啟動(dòng)初始化節(jié)點(diǎn)從 Zookeeper 數(shù)據(jù)節(jié)點(diǎn)讀取數(shù)據(jù),并在該節(jié)點(diǎn)上注冊(cè)一個(gè)數(shù)據(jù)變更
Watcher
· 數(shù)據(jù)變更:當(dāng)變更數(shù)據(jù)時(shí),更新 Zookeeper 對(duì)應(yīng)節(jié)點(diǎn)數(shù)據(jù),Zookeeper會(huì)將數(shù)據(jù)變更通知發(fā)到各客戶
端,客戶端接到通知后重新讀取變更后的數(shù)據(jù)即可。
負(fù)載均衡
zk 的命名服務(wù)
命名服務(wù)是指通過(guò)指定的名字來(lái)獲取資源或者服務(wù)的地址,利用 zk 創(chuàng)建一個(gè)全局的路徑,這個(gè)路徑就可以作為一個(gè)名字,指向集群中的集群,提供的服務(wù)的地址,或者一個(gè)遠(yuǎn)程的對(duì)象等等。
分布式通知和協(xié)調(diào)
對(duì)于系統(tǒng)調(diào)度來(lái)說(shuō):操作人員發(fā)送通知實(shí)際是通過(guò)控制臺(tái)改變某個(gè)節(jié)點(diǎn)的狀態(tài),然后 zk 將這些變化發(fā)送給注冊(cè)了這個(gè)節(jié)點(diǎn)的 watcher 的所有客戶端。對(duì)于執(zhí)行情況匯報(bào):每個(gè)工作進(jìn)程都在某個(gè)目錄下創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn)。并攜帶工作的進(jìn)度數(shù)據(jù),這樣匯總的進(jìn)程可以監(jiān)控目錄子節(jié)點(diǎn)的變化獲得工作進(jìn)度的實(shí)時(shí)的全局情況。
zk 的命名服務(wù)(文件系統(tǒng))
命名服務(wù)是指通過(guò)指定的名字來(lái)獲取資源或者服務(wù)的地址,利用 zk 創(chuàng)建一個(gè)全局的路徑,即是唯一的路徑,這個(gè)路徑就可以作為一個(gè)名字,指向集群中的集群,提供的服務(wù)的地址,或者一個(gè)遠(yuǎn)程的對(duì)象等等。
zk 的配置管理(文件系統(tǒng)、通知機(jī)制)程序分布式的部署在不同的機(jī)器上,將程序的配置信息放在 zk 的 znode 下,當(dāng)有配置發(fā)生改變時(shí),也
就是 znode 發(fā)生變化時(shí),可以通過(guò)改變 zk 中某個(gè)目錄節(jié)點(diǎn)的內(nèi)容,利用 watcher 通知給各個(gè)客戶端,從而更改配置。
Zookeeper 集群管理(文件系統(tǒng)、通知機(jī)制)
所謂集群管理無(wú)在乎兩點(diǎn):是否有機(jī)器退出和加入、選舉 master。對(duì)于第一點(diǎn),所有機(jī)器約定在父目錄下創(chuàng)建臨時(shí)目錄節(jié)點(diǎn),然后監(jiān)聽(tīng)父目錄節(jié)點(diǎn)的子節(jié)點(diǎn)變化消息。一旦有機(jī)器掛掉,該機(jī)器與 zookeeper 的連接斷開(kāi),其所創(chuàng)建的臨時(shí)目錄節(jié)點(diǎn)被刪除,所有其他機(jī)器都收到通知:某個(gè)兄弟目錄被刪除,于是,所有人都知道:它上船了。新機(jī)器加入也是類似,所有機(jī)器收到通知:新兄弟目錄加入,highcount 又有了,對(duì)于第二點(diǎn),我們稍微改變一下,所有機(jī)器創(chuàng)建臨時(shí)順序編號(hào)目錄節(jié)點(diǎn),每次選取編號(hào)最小的機(jī)器作為 master 就好。
Zookeeper 分布式鎖(文件系統(tǒng)、通知機(jī)制)
有了 zookeeper 的一致性文件系統(tǒng),鎖的問(wèn)題變得容易。鎖服務(wù)可以分為兩類,一個(gè)是保持獨(dú)占,另一個(gè)是控制時(shí)序。對(duì)于第一類,我們將 zookeeper 上的一個(gè) znode 看作是一把鎖,通過(guò) createznode的方式來(lái)實(shí)現(xiàn)。所
有客戶端都去創(chuàng)建 /distribute_lock 節(jié)點(diǎn),最終成功創(chuàng)建的那個(gè)客戶端也即擁有了這把鎖。用完刪除掉自己創(chuàng)建的 distribute_lock 節(jié)點(diǎn)就釋放出鎖。對(duì)于第二類, /distribute_lock 已經(jīng)預(yù)先存在,所有客戶端在它下面創(chuàng)建臨時(shí)順序編號(hào)目錄節(jié)點(diǎn),和選master 一樣,編號(hào)最小的獲得鎖,用完刪除,依次方便。Zookeeper 隊(duì)列管理(文件系統(tǒng)、通知機(jī)制)
兩種類型的隊(duì)列:
(1)同步隊(duì)列,當(dāng)一個(gè)隊(duì)列的成員都聚齊時(shí),這個(gè)隊(duì)列才可用,否則一直等待所有成員到達(dá)。
(2)隊(duì)列按照 FIFO 方式進(jìn)行入隊(duì)和出隊(duì)操作。
第一類,在約定目錄下創(chuàng)建臨時(shí)目錄節(jié)點(diǎn),監(jiān)聽(tīng)節(jié)點(diǎn)數(shù)目是否是我們要求的數(shù)目。
第二類,和分布式鎖服務(wù)中的控制時(shí)序場(chǎng)景基本原理一致,入列有編號(hào),出列按編號(hào)。在特定的目錄下
創(chuàng)建 PERSISTENT_SEQUENTIAL 節(jié)點(diǎn),創(chuàng)建成功時(shí)Watcher 通知等待的隊(duì)列,隊(duì)列刪除序列號(hào)最小的節(jié)點(diǎn)用以消費(fèi)。此場(chǎng)景下Zookeeper 的 znode 用于消息存儲(chǔ),znode 存儲(chǔ)的數(shù)據(jù)就是消息隊(duì)列中的消息內(nèi)容,SEQUENTIAL 序列號(hào)就是消息的編號(hào),按序取出即可。由于創(chuàng)建的節(jié)點(diǎn)是持久化的,所以不必?fù)?dān)心隊(duì)列消息的丟失問(wèn)題。
RabbitMQ
1. 什么是MQ
MQ就是消息隊(duì)列。是軟件和軟件進(jìn)行通信的中間件產(chǎn)品
2. MQ的優(yōu)點(diǎn)
- 異步處理 - 相比于傳統(tǒng)的串行、并行方式,提高了系統(tǒng)吞吐量。
- 應(yīng)用解耦 - 系統(tǒng)間通過(guò)消息通信,不用關(guān)心其他系統(tǒng)的處理。
- 流量削鋒 - 可以通過(guò)消息隊(duì)列長(zhǎng)度控制請(qǐng)求量;可以緩解短時(shí)間內(nèi)的高并發(fā)請(qǐng)求。
- 日志處理 - 解決大量日志傳輸。
- 消息通訊 - 消息隊(duì)列一般都內(nèi)置了高效的通信機(jī)制,因此也可以用在純的消息通訊。比如實(shí)
- 現(xiàn)點(diǎn)對(duì)點(diǎn)消息隊(duì)列,或者聊天室等。
3. 解耦、異步、削峰是什么?。
- 解耦:A 系統(tǒng)發(fā)送數(shù)據(jù)到 BCD 三個(gè)系統(tǒng),通過(guò)接口調(diào)用發(fā)送。如果 E 系統(tǒng)也要這個(gè)數(shù)據(jù)呢?那如果 C 系統(tǒng)現(xiàn)在不需要了呢?A 系統(tǒng)負(fù)責(zé)人幾乎崩潰…A 系統(tǒng)跟其它各種亂七八糟的系統(tǒng)嚴(yán)重耦合,A 系統(tǒng)產(chǎn)生一條比較關(guān)鍵的數(shù)據(jù),很多系統(tǒng)都需要 A 系統(tǒng)將這個(gè)數(shù)據(jù)發(fā)送過(guò)來(lái)。如果使用 MQ,A系統(tǒng)產(chǎn)生一條數(shù)據(jù),發(fā)送到 MQ 里面去,哪個(gè)系統(tǒng)需要數(shù)據(jù)自己去 MQ 里面消費(fèi)。如果新系統(tǒng)需 要數(shù)據(jù),直接從 MQ 里消費(fèi)即可;如果某個(gè)系統(tǒng)不需要這條數(shù)據(jù)了,就取消對(duì) MQ 消息的消費(fèi)即可。這樣下來(lái),A 系統(tǒng)壓根兒不需要去考慮要給誰(shuí)發(fā)送數(shù)據(jù),不需要維護(hù)這個(gè)代碼,也不需要考慮 人家是否調(diào)用成功、失敗超時(shí)等情況。就是一個(gè)系統(tǒng)或者一個(gè)模塊,調(diào)用了多個(gè)系統(tǒng)或者模塊,互相之間的調(diào)用很復(fù)雜,維護(hù)起來(lái)很麻煩。但是其實(shí)這個(gè)調(diào)用是不需要直接同步調(diào)用接口的,如果用 MQ 給它異步化解耦。
- 異步:A 系統(tǒng)接收一個(gè)請(qǐng)求,需要在自己本地寫庫(kù),還需要在 BCD 三個(gè)系統(tǒng)寫庫(kù),自己本地寫庫(kù) 要 3ms,BCD 三個(gè)系統(tǒng)分別寫庫(kù)要 300ms、450ms、200ms。最終請(qǐng)求總延時(shí)是 3 + 300 + 450 + 200 = 953ms,接近 1s,用戶感覺(jué)搞個(gè)什么東西,慢死了慢死了。用戶通過(guò)瀏覽器發(fā)起請(qǐng)求。 如果使用 MQ,那么 A 系統(tǒng)連續(xù)發(fā)送 3 條消息到 MQ 隊(duì)列中,假如耗時(shí) 5ms,A 系統(tǒng)從接受一個(gè) 請(qǐng)求到返回響應(yīng)給用戶,總時(shí)長(zhǎng)是 3 + 5 = 8ms。
- 削峰:減少高峰時(shí)期對(duì)服務(wù)器壓力
4. 消息隊(duì)列有什么缺點(diǎn)
5. 你們公司生產(chǎn)環(huán)境用的是什么消息中間件?
這個(gè)首先你可以說(shuō)下你們公司選用的是什么消息中間件,比如用的是RabbitMQ,然后可以初步給一些你對(duì)不同MQ中間件技術(shù)的選型分析。
舉個(gè)例子:比如說(shuō)ActiveMQ是老牌的消息中間件,國(guó)內(nèi)很多公司過(guò)去運(yùn)用的還是非常廣泛的,功能很強(qiáng)大。
但是問(wèn)題在于沒(méi)法確認(rèn)ActiveMQ可以支撐互聯(lián)網(wǎng)公司的高并發(fā)、高負(fù)載以及高吞吐的復(fù)雜場(chǎng)景,在國(guó)內(nèi)互聯(lián)網(wǎng)公司落地較少。而且使用較多的是一些傳統(tǒng)企業(yè),用ActiveMQ做異步調(diào)用和系統(tǒng)解耦。
然后你可以說(shuō)說(shuō)RabbitMQ,他的好處在于可以支撐高并發(fā)、高吞吐、性能很高,同時(shí)有非常完善便捷的后臺(tái)管理界面可以使用。
另外,他還支持集群化、高可用部署架構(gòu)、消息高可靠支持,功能較為完善。
而且經(jīng)過(guò)調(diào)研,國(guó)內(nèi)各大互聯(lián)網(wǎng)公司落地大規(guī)模RabbitMQ集群支撐自身業(yè)務(wù)的case較多,國(guó)內(nèi)各種中小型互聯(lián)網(wǎng)公司使用RabbitMQ的實(shí)踐也比較多。
除此之外,RabbitMQ的開(kāi)源社區(qū)很活躍,較高頻率的迭代版本,來(lái)修復(fù)發(fā)現(xiàn)的bug以及進(jìn)行各種優(yōu)化,因此綜合考慮過(guò)后,公司采取了RabbitMQ。
但是RabbitMQ也有一點(diǎn)缺陷,就是他自身是基于erlang語(yǔ)言開(kāi)發(fā)的,所以導(dǎo)致較為難以分析里面的源碼,也較難進(jìn)行深層次的源碼定制和改造,畢竟需要較為扎實(shí)的erlang語(yǔ)言功底才可以。
然后可以聊聊RocketMQ,是阿里開(kāi)源的,經(jīng)過(guò)阿里的生產(chǎn)環(huán)境的超高并發(fā)、高吞吐的考驗(yàn),性能卓越,同時(shí)還支持分布式事務(wù)等特殊場(chǎng)景。
而且RocketMQ是基于Java語(yǔ)言開(kāi)發(fā)的,適合深入閱讀源碼,有需要可以站在源碼層面解決線上生產(chǎn)問(wèn)題,包括源碼的二次開(kāi)發(fā)和改造。
另外就是Kafka。Kafka提供的消息中間件的功能明顯較少一些,相對(duì)上述幾款MQ中間件要少很多。
但是Kafka的優(yōu)勢(shì)在于專為超高吞吐量的實(shí)時(shí)日志采集、實(shí)時(shí)數(shù)據(jù)同步、實(shí)時(shí)數(shù)據(jù)計(jì)算等場(chǎng)景來(lái)設(shè)計(jì)。
因此Kafka在大數(shù)據(jù)領(lǐng)域中配合實(shí)時(shí)計(jì)算技術(shù)(比如Spark Streaming、Storm、Flink)使用的較多。但是在傳統(tǒng)的MQ中間件使用場(chǎng)景中較少采用。
6. Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么優(yōu)缺點(diǎn)?
7. MQ 有哪些常見(jiàn)問(wèn)題?如何解決這些問(wèn)題?
8. 什么是RabbitMQ?
RabbitMQ是一款開(kāi)源的,Erlang編寫的,消息中間件; 最大的特點(diǎn)就是消費(fèi)并不需要確保提供方 存在,實(shí)現(xiàn)了服務(wù)之間的高度解耦 可以用它來(lái):解耦、異步、削峰。
9. rabbitmq 的使用場(chǎng)景
(1)服務(wù)間異步通信
(2)順序消費(fèi)
(3)定時(shí)任務(wù)
(4)請(qǐng)求削峰
10. RabbitMQ基本概念
11. RabbitMQ的工作模式
12. 如何保證RabbitMQ消息的順序性?
- 拆分多個(gè) queue(消息隊(duì)列),每個(gè) queue(消息隊(duì)列) 一個(gè) consumer(消費(fèi)者),就是多一些 queue(消息隊(duì)列)而已,確實(shí)是麻煩點(diǎn);
- 或者就一個(gè) queue (消息隊(duì)列)但是對(duì)應(yīng)一個(gè) consumer(消費(fèi)者),然后這個(gè) consumer(消費(fèi)者)內(nèi)部用內(nèi)存隊(duì)列做排隊(duì),然后分發(fā)給底層不同的 worker 來(lái)處理。
13. 消息如何分發(fā)?
- 若該隊(duì)列至少有一個(gè)消費(fèi)者訂閱,消息將以循環(huán)(round-robin)的方式發(fā)送給消費(fèi)者。每條消息只會(huì)分發(fā)給一個(gè)訂閱的消費(fèi)者(前提是消費(fèi)者能夠正常處理消息并進(jìn)行確認(rèn))。通過(guò)路由可實(shí)現(xiàn)多消費(fèi)的功能
14. 消息怎么路由?

15. 消息基于什么傳輸?

16. 如何保證消息不被重復(fù)消費(fèi)?或者說(shuō),如何保證消息消費(fèi)時(shí)的冪等性?
17. 如何確保消息正確地發(fā)送至 RabbitMQ? 如何確保消息接收方消費(fèi)了消息?
18. 如何保證RabbitMQ消息的可靠傳輸?

19. 為什么不應(yīng)該對(duì)所有的 message 都使用持久化機(jī)制?
20. 如何保證高可用的?RabbitMQ 的集群

21. 如何解決消息隊(duì)列的延時(shí)以及過(guò)期失效問(wèn)題?消息隊(duì)列滿了以后該怎么處理?有幾百萬(wàn)消息持續(xù)積壓幾小時(shí),怎么辦?
22. 設(shè)計(jì)MQ思路
23.RoctetMq的架構(gòu)
- NameServer
- Broker
- Producer
- Producer的負(fù)載均衡
- 發(fā)送的三種策略
- Consumer
- 推拉消費(fèi)模式
- 集群還是廣播
- Consumer的負(fù)載均衡
24. RocketMq消息模型(專業(yè)術(shù)語(yǔ))
- Message
- Topic
- Tag
- Group
- Message Queue
- offset
25.核心問(wèn)題
- 順序消息
- 消息過(guò)濾
- 消息去重
- 分布式事務(wù)消息
- 消息的可用性
- 刷盤實(shí)現(xiàn)
- 負(fù)載均衡