1. 程式人生 > 其它 >阿里一面,說說你知道訊息中介軟體的應用場景有哪些?

阿里一面,說說你知道訊息中介軟體的應用場景有哪些?

1、前言

又到了金三銀四的時候,大家都按耐不住內心的躁動,我在這裡給大家分享下之前面試中遇到的一個知識點(MQ的應用場景),如有不足,歡迎大佬們指點指點。

訊息中介軟體應用背景

提高系統性能首先考慮的是資料庫的優化,但是資料庫因為歷史原因,橫向擴充套件是一件非常複雜的工程,所有我們一般會盡量把流量都擋在資料庫之前。不管是無限的橫向擴充套件伺服器,還是縱向阻隔到達資料庫的流量,都是這個思路。阻隔直達資料庫的流量,快取元件和訊息元件是兩大殺器。

2、MQ簡介

MQ:Message queue,訊息佇列,就是指儲存訊息的一個容器。

現在常用的MQ元件有activeMQ、rabbitMQ、rocketMQ,當然近年來火熱的kafka,從某些場景來說,也是MQ,不過kafka的功能更加強大,雖然不同的MQ都有自己的特點和優勢,但是,不管是哪種MQ,都有MQ本身自帶的一些特點。

常用訊息佇列比較

特性 ActiveMQ RabbitMQ RocketMQ Kafka
生產者消費者模式 支援 支援 支援 支援
釋出訂閱模式 支援 支援 支援 支援
請求迴應模式 支援 支援 不支援 不支援
Api完備性
多語言支援 支援 支援 java 支援
單機吞吐量 萬級 萬級 萬級 十萬級
訊息延遲 微秒級 毫秒級 毫秒級
可用性 高(主從) 高(主從) 非常高(分散式) 非常高(分散式)
訊息丟失 理論上不會丟失 理論上不會丟失
文件的完備性 教高
提供快速入門
社群活躍度
商業支援 商業雲 商業雲

3、MQ特點

先進先出

先進先出,是佇列最明顯的特點。訊息佇列的順序在入隊的時候就基本已經確定了,一般是不需人工干預的。而且,最重要的是,資料是隻有一條資料在使用中。 這也是MQ在諸多場景被使用的原因。

釋出訂閱

釋出訂閱是一種很高效的處理方式,如果不發生阻塞,基本可以當做是同步操作。這種處理方式能非常有效的提升伺服器利用率,這樣的應用場景非常廣泛。

持久化

持久化確保MQ的使用不只是一個部分場景的輔助工具,而是讓MQ能像資料庫一樣儲存核心的資料,保證MQ的可靠性。

分散式

在現在大流量、大資料的使用場景下,只支援單體應用的伺服器軟體基本是無法使用的,支援分散式的部署,才能被廣泛使用。而且,MQ的定位就是一個高效能的中介軟體。

4、應用場景

訊息佇列中介軟體是分散式系統中重要的元件,主要解決應用解耦,非同步訊息,流量削鋒、海量日誌資料同步、分散式事務等問題,實現高效能,高可用,可伸縮和最終一致性架構。

4.1 應用解耦

場景說明:使用者下單後,訂單系統需要通知庫存系統。傳統的做法是,訂單系統呼叫庫存系統的介面。

傳統模式的缺點:假如庫存系統無法訪問,則訂單減庫存將失敗,從而導致訂單失敗,訂單系統與庫存系統耦合度高,容易出現雪崩事故。

引入應用訊息佇列後的方案

訂單系統:使用者下單後,訂單系統完成持久化處理,將訊息寫入訊息佇列,返回使用者訂單下單成功。
庫存系統:訂閱下單的訊息,採用pull/push的方式,獲取下單資訊,庫存系統根據下單資訊,進行庫存操作。
解決問題關鍵步驟:在下單時庫存系統不能正常使用,也不影響正常下單,因為下單後,訂單系統寫入訊息佇列就不再關心其他的後續操作了,只要達成最終一致性即可。實現訂單系統與庫存系統的應用解耦。

4.2 非同步訊息

場景說明:使用者註冊後,需要發註冊郵件和註冊簡訊。傳統的做法有兩種:序列的方式、並行方式。

  1. 序列方式:將註冊資訊寫入資料庫成功後,傳送註冊郵件,再發送註冊簡訊。以上三個任務全部完成後,返回給客戶端。

  2. 並行方式:將註冊資訊寫入資料庫成功後,傳送註冊郵件的同時,傳送註冊簡訊。以上三個任務完成後,返回給客戶端。與序列的差別是,並行的方式可以提高處理的時間。

    問題分析

    假設三個業務節點每個使用50毫秒鐘,不考慮網路等其他開銷,則序列方式的時間是150毫秒,並行的時間可能是100毫秒。
    因為CPU在單位時間內處理的請求數是一定的,假設CPU1秒內吞吐量是100次。則序列方式1秒內CPU可處理的請求量是7次(1000/150)。並行方式處理的請求量是10次(1000/100)
    如以上案例描述,傳統的方式系統的效能(併發量,吞吐量,響應時間)會有瓶頸。

    將傳送註冊郵件和註冊簡訊的步驟通過訊息佇列解耦

    由以上架構可知,使用者的響應時間相當於是註冊資訊寫入資料庫的時間,也就是50毫秒。註冊郵件,傳送簡訊寫入訊息佇列後,直接返回,因此寫入訊息佇列的速度很快,基本可以忽略,因此使用者的響應時間可能是50毫秒。因此架構改變後,系統的吞吐量提高到每秒20 QPS。比序列提高了3倍,比並行提高了兩倍。

4.3 流量削鋒

流量削鋒也是訊息佇列中的常用場景,一般在秒殺或團搶活動中使用廣泛。

場景說明:秒殺活動,一般會因為流量過大,導致流量暴增,應用或者資料庫掛掉。為解決這個問題,一般需要在應用前端加入訊息佇列。

架構如下

加入訊息佇列的好處

  1. 可以控制活動的人數
  2. 可以緩解短時間內高流量壓垮應用

使用者的請求,伺服器接收後,首先寫入訊息佇列。假如訊息佇列長度超過最大數量,則直接拋棄使用者請求或跳轉到錯誤頁面。
秒殺業務根據訊息佇列中的請求資訊,再做後續處理。

4.4 海量日誌資料同步

場景說明:在微服務體系下,專案往往是叢集部署,那麼就需要一個統一日誌平臺來查詢各個例項的日誌,但叢集中的日誌資訊往往都是海量資料,單一的日誌採集工具不能滿足業務的需要,因此需要將訊息佇列用在日誌處理中,比如Kafka的應用,解決大量日誌傳輸的問題。

架構簡化如下

架構說明

  1. 日誌採集客戶端,負責日誌資料採集,定時寫受寫入Kafka佇列
  2. Kafka訊息佇列,負責日誌資料的接收,儲存和轉發
  3. 日誌處理應用:訂閱並消費kafka佇列中的日誌資料

4.5 分散式事物

分散式事務又分為強一致,弱一致,和最終一致性

  1. 強一致

    當更新操作完成之後,任何多個後續程序或者執行緒的訪問都會返回最新的更新過的值。這種是對使用者最友好的,就是使用者上一次寫什麼,下一次就保證能讀到什麼。根據 CAP 理論,這種實現需要犧牲可用性。

  2. 弱一致

    系統並不保證續程序或者執行緒的訪問都會返回最新的更新過的值。系統在資料寫入成功之後,不承諾立即可以讀到最新寫入的值,也不會具體的承諾多久之後可以讀到。

  3. 最終一致

    弱一致性的特定形式。系統保證在沒有後續更新的前提下,系統最終返回上一次更新操作的值。在沒有故障發生的前提下,不一致視窗的時間主要受通訊延遲,系統負載和複製副本的個數影響。DNS 是一個典型的最終一致性系統。

在分散式系統中,同時滿足“CAP定律”中的一致性、可用性和分割槽容錯性三者是幾乎不可能的。在網際網路領域的絕大多數的場景,都需要犧牲強一致性來換取系統的高可用性,系統往往只需要保證“最終一致性”,只要這個最終時間是在使用者可以接受的範圍內即可,這時候我們只需要用短暫的資料不一致就可以達到我們想要效果。

場景說明:比如有訂單,庫存兩個資料,一個下單過程簡化為,加一個訂單,減一個庫存。 而訂單和庫存是獨立的服務,那怎麼保證資料一致性。

遠端呼叫最鬱悶的地方就是,結果有3種,成功、失敗和超時。 超時的話,成功失敗都有可能。一般的解決方案,大多數的做法是藉助mq來做最終一致。

實現最終一致

通過上面的架構可能會想到這些問題

本地先執行事務,執行成功了就發個訊息過去,消費端拿到訊息執行自己的事務。
比如a,b兩個服務,服務a非同步呼叫服務b,如果服務b失敗了,或者成功,或者超時,那麼怎麼用mq讓他們最終一致呢?

參照於本地事務的概念可將該場景分為三種情況解決

  1. 第一種情況:假設a,b都正常執行,那整個業務正常結束;
  2. 第二種情況:假設b超時,那麼需要MQ給b重發訊息(b服務要做冪等),如果出現重發失敗的話,需要看情況,是中斷服務,還是繼續重發,甚至人為干預;
  3. 第三種情況:假設a,b之中的一個失敗了,失敗的服務利用MQ給其他的服務傳送訊息,其他的服務接收訊息,查詢本地事務記錄日誌,如果本地也失敗,刪除收到的訊息(表示訊息消費成功),如果本地成功的話,則需要呼叫補償介面進行補償(需要每個服務都提供業務補償介面)。

需要特別注意

MQ這裡有個坑,通常只適用於只允許第一個操作失敗的場景,也就是第一個成功之後必須保證後面的操作在業務上沒障礙,不然後面失敗了前面不好回滾,只允許系統異常的失敗,不允許業務上的失敗,通常業務上失敗一次後面基本上也不太可能成功了,要是因為網路或宕機引起的失敗可以通過重試解決,如果業務異常,那就只能發訊息給服務a讓他們做補償了吧?通常是通過第三方進行補償,各個服務需要提供補償介面,設計正規化裡通常不允許消費下游業務失敗。

5、總結

MQ在分散式系統開發的場景下使用的越來越多,處理的業務能力也越來越強,所以掌握MQ的使用場景是很要必要的。通過掌握MQ,即可解決大多數業務場景,也可在面試中加分,提高自己的核心競爭力。

最後,外出打工不易,希望各位兄弟找到自己心儀的工作,虎年發發發

也希望兄弟們能關注、點贊、收藏、評論支援一波,非常感謝大家!