成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官靈魂暴擊!消息不丟不重,消息隊列咋選?

開發(fā) 前端
RabbitMQ 提供了兩種確認機制:普通確認模式和批量確認模式。在普通確認模式下,生產(chǎn)者每發(fā)送一條消息,就會等待 Broker 的確認,確認收到了,才會發(fā)送下一條。要是沒收到確認,那就可能需要重試。

兄弟們,今天咱們來聊聊面試的時候,面試官最愛問的一個問題,那就是消息隊列的選擇,而且還專門盯著 "消息不丟不重" 這倆核心指標使勁兒薅。咱設(shè)想這么個場景啊,你正襟危坐,面試官推了推眼鏡,似笑非笑地說:"小伙子,聽說你用過消息隊列,那你給我講講,要是項目里要求消息不丟不重,你咋選合適的 MQ 呢?" 這時候,要是你支支吾吾說不明白,那可就芭比 Q 了,說不定面試官心里都在想:"這孩子,怕是連消息隊列的門都沒摸著吧。" 

所以咱今天就把這事兒掰扯明白,讓你在面試官面前,那就是妥妥的 "消息隊列小靈通",啥問題都能接得住。

一、消息不丟不重:為啥是 MQ 的核心命門?

咱先搞清楚,為啥消息不丟不重這么重要。咱舉個簡單的例子,就說電商場景吧,用戶下了個訂單,這訂單消息要是丟了,那商家可就不知道用戶買了啥,用戶等著收貨也等不到,這不得急眼?要是消息重復(fù)了,商家可能就會發(fā)兩次貨,這成本可就上去了。再比如金融場景,那每一筆交易消息都至關(guān)重要,丟了或者重復(fù)了,那可能就是實實在在的資金損失啊。所以說,消息不丟不重,那就是消息隊列的 "生命線",是咱選擇 MQ 時必須要過的 "生死關(guān)"。

(一)消息丟失:那些讓人頭疼的坑

消息丟失可能發(fā)生在三個地方:生產(chǎn)者端、消費者端、Broker 端。生產(chǎn)者端可能因為網(wǎng)絡(luò)問題,消息沒發(fā)送到 Broker 就沒了;消費者端可能因為處理消息的時候出錯,還沒處理完就認為消息已經(jīng)消費了;Broker 端可能因為存儲故障,比如磁盤壞了,消息還沒來得及持久化就沒了。

(二)消息重復(fù):那些讓人無奈的煩惱

消息重復(fù)也有幾個原因,生產(chǎn)者端可能因為重試機制,導(dǎo)致消息重復(fù)發(fā)送;Broker 端可能在復(fù)制消息的時候,因為網(wǎng)絡(luò)問題,導(dǎo)致消費者收到重復(fù)的消息;消費者端可能因為消費成功后,給 Broker 的確認消息沒發(fā)送成功,Broker 以為沒消費,又發(fā)了一次。

二、主流 MQ 大閱兵:各顯神通的防丟防重術(shù)

現(xiàn)在市面上主流的 MQ 有不少,像 RabbitMQ、Kafka、RocketMQ,還有 ActiveMQ、Pulsar 等等。咱今天就重點挑幾個大家常用的來嘮嘮,看看它們在防丟防重方面都有啥絕招。

(一)RabbitMQ:英倫紳士的嚴謹范兒

RabbitMQ 就像個英倫紳士,講究的就是一個嚴謹、規(guī)范。它在防丟防重方面,有不少實用的機制。

1. 生產(chǎn)者端:確認機制顯身手

RabbitMQ 提供了兩種確認機制:普通確認模式和批量確認模式。在普通確認模式下,生產(chǎn)者每發(fā)送一條消息,就會等待 Broker 的確認,確認收到了,才會發(fā)送下一條。要是沒收到確認,那就可能需要重試。不過這效率可能有點低,所以就有了批量確認模式,生產(chǎn)者發(fā)送一批消息,然后等待 Broker 對這一批的確認。這樣效率能提高一些,但要是其中有一條消息沒確認,可能就得把這一批都重試,有點 "一損俱損" 的意思。

還有一種是異步確認模式,生產(chǎn)者發(fā)送消息后,不需要阻塞等待確認,而是通過回調(diào)函數(shù)來處理確認和失敗的情況。這樣就不會阻塞生產(chǎn)者的發(fā)送流程,提高了效率。

2. 消費者端:手動確認保安全

RabbitMQ 默認是自動確認消息的,也就是消費者收到消息后,Broker 就認為消息已經(jīng)消費了。但這樣要是消費者處理消息的時候出錯了,消息就丟了。所以咱一般會開啟手動確認模式,消費者處理完消息后,手動發(fā)送一個確認信號給 Broker,Broker 才會把消息從隊列中移除。要是處理過程中出錯了,消費者可以發(fā)送拒絕信號,讓 Broker 把消息重新放回隊列,或者丟棄。

3. Broker 端:持久化存儲加鏡像隊列

RabbitMQ 的持久化包括隊列持久化和消息持久化。隊列持久化就是把隊列的元數(shù)據(jù)存儲到磁盤上,這樣 Broker 重啟后,隊列還在。消息持久化就是把消息存到磁盤上,而不是內(nèi)存里,這樣即使 Broker 宕機了,重啟后消息還能恢復(fù)。不過要注意,消息持久化到磁盤也不是立馬就存進去的,可能會先存在緩存里,然后批量寫入磁盤,所以還是有可能丟失一部分消息,這時候就需要結(jié)合事務(wù)機制或者確認機制來保證。

鏡像隊列則是把隊列的數(shù)據(jù)復(fù)制到多個 Broker 節(jié)點上,這樣即使一個 Broker 節(jié)點掛了,其他節(jié)點還有隊列的數(shù)據(jù),保證了高可用性,也間接防止了消息丟失。

4. 防重復(fù):去重靠業(yè)務(wù)

RabbitMQ 本身在防重復(fù)方面沒有特別強的機制,主要還是靠業(yè)務(wù)層來處理。比如給每條消息加一個唯一的 ID,消費者在處理消息前,先檢查這個 ID 是否已經(jīng)處理過了,如果處理過了,就跳過。

(二)Kafka:暴躁老哥的高效防丟術(shù)

Kafka 就像個暴躁老哥,追求的是高吞吐量、低延遲,但在防丟防重方面,也有自己的一套辦法,雖然不像 RabbitMQ 那么嚴謹,但勝在高效。

1. 生產(chǎn)者端:acks 參數(shù)定乾坤

Kafka 的生產(chǎn)者發(fā)送消息時,通過 acks 參數(shù)來控制消息的確認機制。acks=0 的時候,生產(chǎn)者發(fā)送完消息就不管了,也不等待 Broker 的確認,這時候消息很容易丟失,一般很少用。acks=1 的時候,只要 Leader 節(jié)點收到消息,就給生產(chǎn)者確認,這時候如果 Follower 節(jié)點還沒同步消息,Leader 節(jié)點掛了,消息就丟了。acks=-1(或者 all)的時候,需要所有的 In - Sync Replicas(ISR)中的節(jié)點都收到消息,才給生產(chǎn)者確認,這樣消息的可靠性最高,但吞吐量會有所下降。

還有生產(chǎn)者的重試機制,當(dāng)發(fā)送消息失敗時,生產(chǎn)者會自動重試,不過要注意重試可能會導(dǎo)致消息重復(fù),所以需要消費者端做好去重處理。

2. 消費者端:offset 管理是關(guān)鍵

Kafka 的消費者通過 offset 來記錄消息的消費位置。默認情況下,消費者會自動提交 offset,也就是在消費消息的同時,定期向 Broker 提交自己當(dāng)前的 offset。但這樣如果消費者在處理消息的時候掛了,可能有一部分消息已經(jīng)處理了,但 offset 還沒提交,或者 offset 已經(jīng)提交了,但消息還沒處理完,就會導(dǎo)致消息重復(fù)或者丟失。所以咱一般會使用手動提交 offset 的方式,消費者處理完消息后,手動提交 offset,這樣就能保證消息要么處理完并提交 offset,要么沒處理完,重新消費。

3. Broker 端:副本機制保可靠

Kafka 的 Broker 端通過副本機制來保證消息的可靠性。每個分區(qū)都有多個副本,包括一個 Leader 副本和多個 Follower 副本。生產(chǎn)者發(fā)送消息到 Leader 副本,F(xiàn)ollower 副本從 Leader 副本同步消息。當(dāng) Leader 副本掛了,會從 ISR 中的 Follower 副本中選舉出新的 Leader 副本,保證消息不會丟失。

4. 防重復(fù):冪等性加事務(wù)

Kafka 從 0.11 版本開始支持冪等性生產(chǎn)者,通過給每條消息生成一個唯一的 PID 和 Sequence Number,保證即使生產(chǎn)者重試,也不會產(chǎn)生重復(fù)的消息。不過冪等性只能保證單個分區(qū)內(nèi)的消息不重復(fù),跨分區(qū)和跨會話的情況下,還是需要使用事務(wù)機制。事務(wù)機制可以保證在多個分區(qū)上的操作要么全部成功,要么全部失敗,從而避免消息重復(fù)或丟失。

(三)RocketMQ:六邊形戰(zhàn)士的全能防丟防重

RocketMQ 就像個六邊形戰(zhàn)士,在各個方面都表現(xiàn)得很均衡,防丟防重機制也很完善,啥場景都能應(yīng)對。

1. 生產(chǎn)者端:同步異步確認任選

RocketMQ 的生產(chǎn)者發(fā)送消息時,可以選擇同步發(fā)送、異步發(fā)送和單向發(fā)送。同步發(fā)送會等待 Broker 的確認,確保消息發(fā)送成功,適合對可靠性要求高的場景。異步發(fā)送則是發(fā)送消息后,通過回調(diào)函數(shù)來處理確認結(jié)果,不阻塞線程,提高效率。單向發(fā)送就是只發(fā)送消息,不等待確認,適合對可靠性要求不高,但追求吞吐量的場景。

還有生產(chǎn)者的重試策略,當(dāng)發(fā)送消息失敗時,會按照一定的策略重試,比如默認重試 2 次,而且可以配置不同的重試間隔。

2. 消費者端:手動確認加順序消費

RocketMQ 的消費者可以選擇集群消費和廣播消費模式。在集群消費模式下,默認是自動提交消費進度,但也可以開啟手動提交,消費者處理完消息后,手動調(diào)用 ack 方法來確認消息已經(jīng)消費。對于順序消息,消費者會按照消息的順序來消費,并且在處理完一條消息后,才會處理下一條,保證了順序性和可靠性。

3. Broker 端:持久化存儲加主從架構(gòu)

RocketMQ 的 Broker 端通過 CommitLog 文件來存儲消息,并且支持異步刷盤和同步刷盤。異步刷盤是指消息先寫入內(nèi)存緩沖區(qū),然后定期寫入磁盤,吞吐量高,但可能會丟失少量消息。同步刷盤是指消息必須寫入磁盤后,才給生產(chǎn)者確認,可靠性高,但吞吐量低。

主從架構(gòu)則是將 Broker 節(jié)點分為 Master 節(jié)點和 Slave 節(jié)點,Master 節(jié)點負責(zé)處理讀寫請求,Slave 節(jié)點從 Master 節(jié)點同步數(shù)據(jù),當(dāng) Master 節(jié)點掛了,Slave 節(jié)點可以切換為 Master 節(jié)點,保證服務(wù)的可用性和消息的可靠性。

4. 防重復(fù):唯一鍵加去重服務(wù)器

RocketMQ 在生產(chǎn)者端可以給消息設(shè)置唯一的 Key,消費者端在消費消息時,可以根據(jù)這個 Key 來判斷是否已經(jīng)消費過。另外,RocketMQ 還提供了去重服務(wù)器,可以在 Broker 端對重復(fù)的消息進行去重處理,不過這需要開啟相應(yīng)的配置。

三、實戰(zhàn)選型:到底該翻誰的牌子?

現(xiàn)在咱了解了各個 MQ 在防丟防重方面的機制,那在實際項目中,到底該怎么選呢?咱得結(jié)合具體的場景來分析。

(一)小而美的 RabbitMQ

適合場景:中小型項目,對可靠性要求較高,業(yè)務(wù)場景不太復(fù)雜,比如簡單的訂單通知、短信發(fā)送等。

優(yōu)勢:輕量級,容易部署和維護,社區(qū)活躍,文檔豐富,插件眾多,可以滿足各種個性化需求。

劣勢:吞吐量相對較低,在處理大規(guī)模消息時,性能可能會有所下降,而且集群管理相對復(fù)雜。

(二)吞吐王者 Kafka

適合場景:大數(shù)據(jù)場景,比如日志收集、實時數(shù)據(jù)處理、流量削峰等,對吞吐量和實時性要求很高。

優(yōu)勢:超高的吞吐量,支持海量消息的處理,分布式架構(gòu)設(shè)計,可擴展性強,適合構(gòu)建實時數(shù)據(jù)管道。

劣勢:消息的延遲相對較高,在可靠性要求極高的場景下,需要仔細配置 acks 參數(shù)和副本機制,而且對消息的順序性支持不夠好,除非是單個分區(qū)內(nèi)的順序。

(三)全能選手 RocketMQ

適合場景:大型分布式系統(tǒng),對可靠性、吞吐量、順序性、事務(wù)等都有要求的場景,比如電商、金融等復(fù)雜業(yè)務(wù)場景。

優(yōu)勢:功能全面,支持事務(wù)消息、順序消息、延遲消息等多種特性,高可用性和高可靠性,集群管理相對簡單,適合國內(nèi)的技術(shù)生態(tài)。

劣勢:需要一定的學(xué)習(xí)成本,雖然比 Kafka 簡單,但比 RabbitMQ 還是復(fù)雜一些,而且社區(qū)活躍度相比 Kafka 和 RabbitMQ,稍微差那么一丟丟。

(四)其他 MQ:各有千秋

ActiveMQ:老牌的 MQ,支持多種協(xié)議,比如 JMS、AMQP 等,適合傳統(tǒng)的 Java 企業(yè)應(yīng)用,但性能和吞吐量相對較低,社區(qū)活躍度也不如以前了。

Pulsar:新興的 MQ,支持多租戶、持久化存儲和非持久化存儲,在云原生場景下表現(xiàn)不錯,但普及度還不夠高,生態(tài)還在完善中。

四、避坑指南:這些坑別踩!

(一)過度追求可靠性,忽略性能

有些小伙伴覺得,既然消息不能丟不能重,那就把所有的可靠性機制都打開,比如 Kafka 的 acks=-1,同步刷盤,RocketMQ 的同步刷盤,主從架構(gòu)等等。這樣確實能保證消息的可靠性,但會極大地影響性能,導(dǎo)致吞吐量下降,延遲增加。所以咱得根據(jù)實際場景,在可靠性和性能之間找到一個平衡點。

(二)忽略業(yè)務(wù)層的去重處理

雖然各個 MQ 都有一些防重復(fù)的機制,但都不是萬能的,比如 RabbitMQ 主要靠業(yè)務(wù)層去重,Kafka 的冪等性只能保證單個分區(qū)內(nèi)的去重,RocketMQ 的去重服務(wù)器也需要配置。所以咱在項目中,一定要在業(yè)務(wù)層做好去重處理,比如給消息加唯一 ID,處理前先檢查是否已經(jīng)處理過。

(三)不重視監(jiān)控和報警

即使我們選擇了合適的 MQ,配置了完善的防丟防重機制,也不能掉以輕心。我們需要對 MQ 的運行狀態(tài)進行實時監(jiān)控,比如隊列的堆積情況、消息的發(fā)送和消費速率、Broker 節(jié)點的健康狀態(tài)等等。一旦出現(xiàn)異常,要及時報警,以便快速處理問題,避免消息丟失或重復(fù)的發(fā)生。

五、總結(jié):沒有最好的 MQ,只有最適合的 MQ

回到面試官的問題,消息不丟不重,消息隊列咋選?其實沒有一個標準答案,關(guān)鍵是要結(jié)合項目的具體需求,比如業(yè)務(wù)場景、數(shù)據(jù)量、吞吐量、延遲要求、可靠性要求等等。RabbitMQ 就像個精致的小皮鞋,適合在平坦的小路上走;Kafka 就像個越野卡車,適合在大數(shù)據(jù)的泥濘道路上狂奔;RocketMQ 就像個全能的 SUV,各種路況都能應(yīng)對。

咱在選擇的時候,要先搞清楚項目的核心需求,是要可靠性優(yōu)先,還是性能優(yōu)先,或者是功能全面。然后再深入了解各個 MQ 的特性和機制,看看哪個最符合咱的需求。同時,也要注意在實際使用中,合理配置各個參數(shù),做好業(yè)務(wù)層的處理和監(jiān)控報警,這樣才能讓消息隊列真正發(fā)揮作用,既不丟消息,也不重消息,讓面試官對你刮目相看。

責(zé)任編輯:武曉燕 來源: 石杉的架構(gòu)筆記
相關(guān)推薦

2021-10-22 08:37:13

消息不丟失rocketmq消息隊列

2020-08-17 07:40:19

消息隊列

2024-05-29 14:34:07

2020-10-26 09:19:11

線程池消息

2019-04-15 14:40:46

消息隊列Java編程

2016-11-10 21:00:49

消息存儲數(shù)據(jù)

2024-01-16 08:24:59

消息隊列KafkaRocketMQ

2023-12-26 09:34:47

系統(tǒng)MongoDB存儲

2022-10-09 08:38:17

消息隊列面試官模式

2016-11-02 13:12:31

微信離線消息

2016-10-11 16:31:56

微信服務(wù)器消息

2021-03-08 10:19:59

MQ消息磁盤

2022-08-26 05:24:04

中間件技術(shù)Kafka

2019-12-02 10:51:11

Redis存儲系統(tǒng)

2017-10-11 15:08:28

消息隊列常見

2024-01-26 13:16:00

RabbitMQ延遲隊列docker

2020-06-12 09:40:32

消息隊列Java線程

2021-12-21 07:07:43

HashSet元素數(shù)量

2023-09-06 14:11:03

數(shù)據(jù)庫Redis消息隊列

2022-06-30 08:14:05

Java阻塞隊列
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 综合一区二区三区 | 麻豆视频国产在线观看 | 91视频国产精品 | 男女搞网站 | aaa综合国产 | 亚洲欧美一区二区三区国产精品 | 999热视频| 亚洲一区二区三区欧美 | 欧美激情区 | 亚洲网站在线观看 | 色悠悠久 | 99精品免费久久久久久久久日本 | 欧美综合国产精品久久丁香 | 亚洲三区在线观看 | 久久精品国产久精国产 | av av在线| 国产精品久久久爽爽爽麻豆色哟哟 | 久在线视频| 欧美综合色 | 欧美国产中文 | 精品在线免费看 | 久久爱综合 | 91精品一区二区三区久久久久久 | 人人操日日干 | 精品一区av | 欧美久久久网站 | 国产亚洲一区精品 | 欧美三级网站 | 中文字幕第一页在线 | 日韩精品一区中文字幕 | 人人干人人草 | 精品日韩一区 | 玖玖国产| 国产男女精品 | 综合久久久 | 污片在线免费观看 | 久久91| 亚洲aⅴ一区二区 | 日韩久久久久 | 国产精品久久久久久福利一牛影视 | 亚洲女优在线播放 |