一個故事告訴你什麼是消息隊列

一個故事告訴你什麼是消息隊列

案例

有一天,產品跑來說:“我們要做一個用戶註冊功能,需要在用戶註冊成功後給用戶發一封成功郵件。”

小明(攻城獅):“好,需求很明確了。” 不就提供一個註冊接口,保存用戶信息,同時發起郵件調用,待郵件發送成功後,返回用戶操作成功。沒一會功夫,代碼就寫完了。驗證功能沒問題後,就發佈上線了。

線上正常運行了一段時間,產品匆匆地跑來說:“你做的功能不行啊,運營反饋註冊操作響應太慢,已經有好多用戶流失了。”

小明聽得一身冷汗,趕緊回去改。他發現,原先的以單線程同步阻塞的方式進行郵件發送,確實存在問題。這次,他利用了 JAVA 多線程的特性,另起線程進行郵件發送,主線程直接返回保存結果。測試通過後,趕緊發佈上線。小明心想,這下總沒問題了吧。

沒過多久,產品又跑來了,他說:“現在,註冊操作響應是快多了。但是又有新的問題了,有用戶反應,郵件收不到。能否在發送郵件時,保存一下發送的結果,對於發送失敗的,進行補發。”

小明一聽,哎,又得熬夜加班了。產品看他一臉苦逼的樣子,忙說:“郵件服務這塊,別的團隊都已經做好了,你不用再自己搞了,直接用他們的服務。”

小明趕緊去和郵件團隊溝通,誰知他們的服務根本就不對外開放。這下小明可開始犯愁了,明知道有這麼一個服務,可是偏偏又調用不了。

郵件團隊的人說,“看你愁的,我給你提供了一個類似郵局信箱的東西,你往這信箱裏寫上你要發送的消息,以及我們約定的地址。之後你就不用再操心了,我們自然能從約定的地址中取得消息,進行郵件的相應操作。”

後來,小明才知道,這就是外界廣爲流傳的消息隊列。你不用知道具體的服務在哪,如何調用。你要做的只是將該發送的消息,向你們約定好的地址進行發送,你的任務就完成了。對應的服務自然能監聽到你發送的消息,進行後續的操作。這就是消息隊列最大的特點,將同步操作轉爲異步處理,將多服務共同操作轉爲職責單一的單服務操作,做到了服務間的解耦

哈哈,這下能高枕無憂了。太年輕,哪有萬無一失的技術啊~

不久的一天,你會發現所有業務都替換了郵件發送的方式,統一使用了消息隊列來進行發送。這下僅僅一個郵件服務模塊,難以承受業務方源源不斷的消息,大量的消息堆積在了隊列中。這就需要更多的消費者(郵件服務)來共同處理隊列中的消息,即所謂的分佈式消息處理

未完待續。。。

總結

定義

有了上面的基礎,再看非常官方的解釋應該也能理解了。

消息隊列(英語:Message queue)是一種進程間通信或同一進程的不同線程間的通信方式,軟件的貯列用來處理一系列的輸入,通常是來自用戶。消息隊列提供了異步的通信協議,每一個貯列中的紀錄包含詳細說明的數據,包含發生的時間,輸入設備的種類,以及特定的輸入參數,也就是說:消息的發送者和接收者不需要同時與消息隊列互交。消息會保存在隊列中,直到接收者取回它。 ——維基百科

名詞解釋

解釋還是太官方了,我們來看一個最簡單的架構模型:

  • Producer:消息生產者,負責產生和發送消息到 Broker;
  • Broker:消息處理中心。負責消息存儲、確認、重試等,一般其中會包含多個 queue;
  • Consumer:消息消費者,負責從 Broker 中獲取消息,並進行相應處理;

特性

異步性

將耗時的同步操作,通過以發送消息的方式,進行了異步化處理。減少了同步等待的時間。

鬆耦合

消息隊列減少了服務之間的耦合性,不同的服務可以通過消息隊列進行通信,而不用關心彼此的實現細節,只要定義好消息的格式就行。

分佈式

通過對消費者的橫向擴展,降低了消息隊列阻塞的風險,以及單個消費者產生單點故障的可能性(當然消息隊列本身也可以做成分佈式集羣)。

可靠性

消息隊列一般會把接收到的消息存儲到本地硬盤上(當消息被處理完之後,存儲信息根據不同的消息隊列實現,有可能將其刪除),這樣即使應用掛掉或者消息隊列本身掛掉,消息也能夠重新加載。

發佈了91 篇原創文章 · 獲贊 97 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章