厚積薄發--一文帶您了解阿里云RocketMQ 輕量版消息隊列(MNS)
作者:周新宇、陳濤、李凱
阿里云 RocketMQ 輕量版(MNS)消息隊列是一個輕量、可靠、可擴展且完全托管的分布式消息隊列服務。MNS 能夠幫助應用開發者在他們應用的分布式組件上更輕量的傳遞數據、通知消息,構建松耦合系統。無需管理開銷,而且模型簡單,拆箱即用,自動橫向擴容,無需管理分區等復雜的邏輯運維,是一款 Serverless 消息隊列產品。
MNS 重點聚焦在基準消息隊列的核心能力建設,MNS 經過多年迭代與打磨,盡管內部極為復雜,但一直努力保持其在客戶端的簡單易用,圍繞輕量和集成兩個命題,著力建設更易用的消息隊列產品。

核心優勢
MNS 圍繞輕量消息隊列,提供一系列的輕量級能力。為企業和開發者降低消息產品的復雜度,減少運維開銷,提供更易上手的消息隊列服務。
輕量模型
MNS 提供 1:1 和 1:N 兩種輕量模型,可根據場景自行選擇需要的模型方式,學習成本低,上手快。無需理解復雜的概念模型,無需刻意學習,幾分鐘即可快速上手。
MNS 模型輕量主要體現在資源的操作方面,創建和刪除等都配置有極簡的 API,同時與數據鏈路的 API 屬于同一個 SDK,方便用戶像收發消息那樣進行資源的創建。相反,很多云產品資源的 API 都采用了新的管控 SDK,使用門檻較高。
此外,MNS 的模型和資源是一一對應的,比如使用隊列模型僅需要創建一個 Queue,非常易于上手和使用,而其他一些同類型產品,對于同一個模型會有實例、主題、隊列、分區等多個資源。
輕量協議
采用 HTTP RESTful 標準協議,接入方便,跨網絡能力強,天然擁有支持多語言訪問的能力。官方 SDK 覆蓋各大主流語言,包括C++,C#,.Net,Python,PHP 和 Java,社區貢獻也有用 Go,Node等 。
同時訪問協議簡單通用,即使不想依賴云產品提供SDK ,也可以很容易通過簡單的編碼來訪問 API,接入成本低,開發效率高。
輕量計費

MNS是Serverless輕量計費,相較于按照實例付費,MNS 提供更加輕量的Serverless 計費方式。按照請求量和資源占用情況付費,用多少付多少,無需為額外預留資源買單;同時提供每個月擁有 2000 萬次 API 免費調用額度。這種完全后付費的定價方式可以為企業節約大量閑置資源。
輕量運維
MNS 可以根據應用情況進行彈性擴展,因此,無需擔心容量規劃和預配置。每個隊列的消息數量不限,而且標準隊列能提供幾乎無限的吞吐量(QPS 范圍內);提供 Serverless 化彈性服務,高效快捷,無需對資源做預留,隨取隨用,實時擴縮;更適合產品集成與瞬時隊列場景。
同時MNS提供完善的消息監控消息告警等能力,支持高可靠性和高穩定性,消除管理和運維時的復雜性和研發開銷。
基本模型
MNS 是一個融合了點對點(P2P)和發布訂閱(Pub/Sub)兩種消費模型的消費系統,其中 MNS 的「隊列」是 P2P 消費模型的實現,「主題」是 Pub/Sub 消費模型的實現。
MNS 也是業界鮮有的同時提供兩種混合消費模型的云產品,用戶可以通過「隊列」或者「主題」來實現大部分對消息系統的需求。
隊列(P2P 模型)
隊列模型提供高可靠、高并發的一對一消費模型,即隊列中的每一條消息都只能夠被某一個消費者消費。隊列就像一家旋轉壽司店。壽司店中有多個壽司師傅(生產者)在制作精美的壽司,每一份壽司都是獨特的,顧客(消費者)可以從傳送帶上拿取中意的壽司進行食用(消費)。
隊列是 MNS 的頂級資源,也是消息的存儲實體,有完整的阿里云資源的生命周期,以及完善的權限控制機制。圍繞隊列有三個核心概念:
- 生產者(Producer):生產者負責將消息發送到指定的隊列上,一個隊列接受分布式的生產者并發投遞消息。
- 隊列(Queue):隊列模型對應的物理資源,也是消息的存儲實體,MNS 通過一個分布式的存儲集群來提供隊列的分布式存儲能力。
- 消費者(Consumer):消費者負責從指定的隊列通過輪詢的機制獲取消息,一個隊列接受分布式的消費者并發地消費消息,同時保證同一條消息在可見時間內只會被一個消費者消費。
主題(Pub/Sub 模型)
主題模型提供一對多的發布訂閱模型,支持消息通知。主題就像一份報紙,多個讀者到郵局訂閱了這份報紙。當報紙推出最新一期時,讀者(包括郵局的合作伙伴)可以選擇以下方式來獲取:
- 讓郵局投遞員將報紙都投遞(推送)到家里(特定的地址)。
- 去就近的報刊亭(訂閱點)自行獲取報紙(報紙會先被郵局投遞員集中送到各個報刊亭)。
主題是 MNS 的另一個頂級資源,其也具備消息的存儲能力,對應的 Topic 資源具備完整的阿里云資源的生命周期,以及完善的權限控制機制。圍繞主題也有三個核心概念:
- 生產者(Producer):生產者除了可以把消息發送至隊列,也可以把消息發送到主題上,主題也接受分布式的生產者并發投遞消息。
- 主題(Topic):主題模型對應的物理資源同樣具備消息的存儲能力。
- 訂閱(Subscription):可以為每個主題創建多個訂閱,每個訂閱將收到 Topic 上的完整消息,訂閱的下游可以是多種類型的訂閱者,用戶往往通過訂閱的能力將主題中的消息扇出至多個隊列。
功能特性
MNS 作為一款成熟的消息產品,面向主題和隊列提供了多種功能特性,能夠深入到應用的架構當中,幫助用戶降低業務流程開發的復雜度,讓業務專注于業務邏輯的開發。比如多種消息類型的支持,方便用戶快速實現定時、優先級相關的業務邏輯。
多種消息類型的支持
MNS 隊列支持普通消息、延遲消息、優先消息這3種消息類型。
普通消息是最基礎的消息類型,當一條普通消息發送到了MNS之后,這一條消息就會在隊列中等待用戶的拉取進行消息的消費。
對于延遲消息,用戶可以在發送的時候指定期望這條消息的延遲時間,當到了設定的延遲時間后,那么就可以消費到這條消息。同時,在發送了延遲消息之后,除了可以獲取到消息的一些基本屬性之外,還可以獲取到一個消息句柄,當期望提前取消掉這條延遲消息的時候,我們可以使用這個消息句柄進行Delete。Delete過后,這條消息就不會再投遞出來。通過延遲消息,用戶可以輕松的實現一個分布式的延遲調度系統,在擁有高精度延遲的同時,實現超高的可擴展性和可用性。
對于優先消息,我們在發送消息的時候可以指定消息的優先級,優先級的取值范圍為1到16。優先級的取值越小,那么這條消息的優先級就越高。需要注意的是,優先消息并不保證消息的順序性,優先級越高的消息擁有更容易被消費的可能性,并不意味著優先級低的消息一定會在優先級高的消息消費完成之后才能夠被消費。
高效的長輪訓機制
對于 消息隊列MNS來說 ,用戶需要主動進行消息的拉取,如果拉取的頻率過低,那么就會導致消息的延遲;相對應的,如果拉取的頻率過高,那么又會帶來過多無效的API調用。
為解決這個問題,MNS 隊列提供了長輪訓的機制,可以在一定程度上減少無效API的調用,同時保證消息的及時性。當用戶拉取消息的時候,可以設置這次請求拉取消息的waitseconds,客戶端則會以設置的時間掛一個長輪訓請求到服務端。如果在長輪訓期間發現有消息可以被消費,就會立即返回;如果沒有,就會最多等待長輪訓時間結束之后返回。但需要注意的是,雖然我們可以使用長輪訓來減少無效的API調用,但整體上還是需要一定的消息拉取的并發度,以保證消息的及時性。
靈活的消息生命周期管理

對于隊列中的一條消息,其會具有可見、不可見、刪除這3狀態。當消息發送到隊列中后,這條消息就處于可見的狀態,等待消費者來拉取。當消息被消費者拉取出來之后,消息會進入一段“不可見時間”,在這段“不可見時間”里面,這條消息是不會被再次的拉取出來。但如果在“不可見時間”里面這條消息沒有被刪除,那么這一條消息就會再次的可見,并可以被消費者再一次的從隊列中拉取出來。
除此之外,當有消費者消費到消息,在處理的過程中突然出現問題,例如宕機,那么這一條消息則會在“不可見時間”結束之后再一次的可見,可以被其他的消費者再次消費到。
這里可能就存在一個矛盾點,用戶可能期望有消費者宕機之后,沒有被正確處理的消息能夠盡快的由其他消費者消費下去,但又由于本身的業務處理時間可能有時候較長,可能會超過隊列上所配置的默認的“不可見時間”,導致消息的重復消費。那么,為解決這種場景,MNS也為用戶提供了可以在消息維度修改某一條消息的“不可見時間”功能。

當用戶收到了一條消息,發現這條消息處理的時間較長會超過隊列所配置的“不可見時間”的時候,用戶可以通過消息的句柄主動調用,修改這一條消息的不可見時間。例如上圖,將這一條消息的不可見時間進行了延長,留給了業務更多的處理時間。當然,同之前的消息消費一樣,當這條消息處理完成之后,也需要調用刪除消息的接口,進行消息消費成功的確認。
消息多訂閱推送

MNS主題提供了一對多廣播消息的能力,我們可以為一個主題創建多個訂閱,路由到不同的Endpoint。用戶只需要將消息發送到主題,就可以將這個一條消息推送到多個訂閱中去。
其次,在一對多廣播消息的能力的基礎上,在訂閱中,MNS還支持訂閱帶有特定標簽的消息。我們在創建訂閱的時候可以指定這個訂閱所關心的消息的Tag,這樣當MNS進行消息推送的時候,就會自動進行消息的過濾,僅將這個訂閱所關心的Tag推送出去。
為了保證消息投遞的可靠性,用戶可以對每個訂閱配置推送策略,可以指定使用退避重試策略或者指數衰減重試的策略。
對于退避重試策略,當消息推送失敗的時候,會重試3次,每一次的重試間隔時間為10到20秒的隨機值。對于指數衰減重試,整體的重試時間為1天,每次的重試時間間隔是指數遞增的(1秒,2秒,,4秒,8秒,...)。
最后,我們還可以配置推送的消息的格式,我們可以在創建訂閱的時候,指定推送格式為XML、JSON或者SIMPLIFIED。對于XML和JSON,推送給訂閱的消息內容,除了會包含發送到主題的消息之外,還會添加例如MessageID、TopicName、SubscriptionName等屬性。而對于SIMPLIFIED,則是直接將發送到主題的消息進行轉發,不會添加額外的屬性。
接入協議
MNS 以HTTP 協議對外提供服務,包含近 30 個 RESTful 的 API,但核心業務場景往往使用 3 個左右的 API 就可以完成研發,非常易于上手。
另外,用戶既可以直接根據 API 進行自行的封裝,也可以直接使用官方所提供的的 SDK 進行集成。用戶僅只需要依賴一個 SDK 就可以完成從服務的開通、資源的創建、再到消息的收發。
在多語言 SDK 方面,MNS 提供了 8 種主流語言的 SDK,包括 Java、Python、C#、Node、PHP、C++、Go 等,同時也支持采用
Java 領域標準的 JMS SDK 接入 MNS。
適用場景解析
相較于 RabbitMQ,ActiveMQ,Kafka
等開源消息隊列,RocketMQ 輕量版 MNS 摒棄了非常復雜的概念模型及臃腫繁多的協議,通過簡單模型,通用的 HTTP RESTful 標準協議即可高效完成消息領域的典型場景。提供完全免運維的消息集成方案,顯著降低開發和維護成本,提升新業務開發效率。
消息廣播(Fanout)場景解析

背景信息:輕量消息隊列 MNS 提供隊列(Queue)和主題(Topic)兩種模型,基本能滿足大多數應用場景。隊列提供的是一對一的共享消息消費模型,采用客戶端主動拉取(Pull)模式。
主題模型提供一對多的廣播消息消費模型,采用服務端主動推送(Push)模式。
推送模式的好處是即時性能較好,但需暴露客戶端地址來接收服務端的消息推送。有些情況下有的信息,例如企業內網,無法暴露推送地址,希望改用拉取(Pull)的方式。雖然消息服務MNS不直接提供這種消費模型,但可以結合主題和隊列來實現一對多的拉取消息消費模型。
解決方案:通過創建訂閱,讓主題將消息先推送到隊列,然后由消費者從隊列拉取消息。這樣既可以做到一對多的廣播消息,又可避免暴露消費者的地址。
超大消息傳輸(Claim Check)場景解析

背景信息 :消息服務MNS的隊列的消息大小最大限制是64 KB,這個限制基本能夠滿足在正常情況下消息作為控制流信息交換通道的需求。但是,在某些特殊場景下,消息數據比較大時,就只能采用消息切片的方式。
下面是不做消息切片,通過OSS來實現傳遞大于64 KB的消息的解決方案。
解決方案
生產者在向消息服務MNS發送消息前,如果發現消息體大于64 KB,則先將消息體數據上傳到OSS。
生產者把數據對應的Object信息發送到消息服務MNS。
消費者從消息服務MNS隊列里讀取消息,判斷消息內容是否為OSS的Object信息。
判斷消息內容是OSS的Object信息,則從OSS下載對應的Object內容,并作為消息體返回給上層程序。
簡單事務消息場景解析
背景信息:一些業務場景需要保證本地操作和消息發送的事務一致性,即消息發送成功,本地操作成功。如果消息發送成功,本地操作失敗,那么發送成功的消息需要回滾。操作流程如圖所示:

解決方案
消息發送成功,事務操作成功時操作步驟如下所示:
- 生產者發送一條事務準備消息到事務消息隊列;
- 生產者發送操作日志消息到操作日志隊列,日志中包含步驟1消息的消息句柄;
- 生產者執行本地事務操作成功;
- 生產者請求修改消息延遲時間,使消息對消費者可見;
- 生產者向操作日志隊列確認操作日志,刪除日志消息;
- 消費者從事務消息隊列中接收事務消息;
- 消費者處理事務消息;
- 消費者請求刪除事務消息。
消息過濾(Message Filter) 場景解析

背景信息
一些場景中需要根據消息內容把消息推送到不同的推送目標,為了達到這一功能,您可以創建多個主題,并為每個主題設置相應的推送目標,但是這樣會增加額外的成本,并且增加了運維的復雜度。為了避免這種情況,消息隊列MNS提供了消息過濾標簽功能。您可以只創建一個主題,并在創建訂閱時設置不同的消息過濾標簽,結合消息的消息過濾標簽,MNS就可以把消息推送到不同的推送目標中。
解決方案
圖示例場景中,在主題 Topic 1 創建 3 個消息過濾標簽不同的訂閱,Subscription 1、Subscription 2和Subscription 3。這 3 個訂閱的推送目標分別是 Queue 1、Queue 2 和
Queue 3。
- 消息的消息過濾標簽和訂閱的消息過濾標簽一致。消息過濾過程如下:
? 消息服務 MNS 將 Message 1 推送到隊列 Queue 1;
? 消息服務 MNS 將 Message 2 推送到隊列 Queue 2。
- 訂閱沒有消息過濾標簽。消息過濾過程如下:
? 消息服務 MNS 將 Message 1推送到隊列Queue 3;
? 消息服務MNS將Message 2推送到隊列Queue 3;
? 消息服務MNS將Message 3推送到隊列Queue 3。
客戶案例及最佳實踐
在線交易 - 應用解耦 - 削峰填谷(典型場景)

場景描述:
淘寶/天貓主站最為核心的系統是交易系統,每一筆交易訂單數據都會有幾百個下游業務系統的關聯,包括物流、購物車、積分、直充、阿里媽媽、流計算分析等,整個系統龐大而且復雜,架構設計稍有不合理,將直接影響主站業務的連續性。
異步解耦:
如此復雜且龐大的系統,若上、下游業務系統緊耦合,那么任意一個子系統不可用都將直接導致核心交易系統不可用;
通過消息隊列實現上、下游業務系統松耦合,那么,即便下游子系統(如物流系統)出現不可用,也不會影響到核心交易系統的正常運轉;
削峰填谷 :
通過消息隊列不僅可以起到系統間解耦的作用,更能在大促、秒殺等大型活動中起到削峰填谷的作用。
每年天貓雙11凌晨,保證核心交易系統的業務處理能力始終為重中之重,每秒數十萬筆的交易訂單處理能力,且逐年線性增長;然而相對的,各大物流系統、銀行的支付系統的業務處理能力卻有限,若不能進行流量緩沖將直接引發這些系統的崩潰。因此,利用消息隊列強大的消息堆積能力則可以很好的起到削峰填谷的作用,將系統壓力全部轉移到消息隊列,從而釋放物流、支付等系統的壓力,保證業務的正常運轉。
直播錄制 - 合流 - 轉碼(Serverless 場景 )
場景描述: 視頻的直播錄制,合流,轉碼是在線教育和在線直播領域的剛需場景,通過 MNS 可以對 FC Serverless 資源進行在線調度,幫助客戶實現異步直播流錄制,合流轉碼等復雜場景。

在線游戲場景
場景描述: 游戲場景存在大量強交互場景的數據流轉,對消息中間件的穩定性和端到端延遲要求極高,自建消息中間件壓力大、不穩定。游戲場景存在大量的指令傳輸以及定時任務,自建邏輯無法解決熱點問題。

通過 MNS 可以實現從游戲網關指令到后臺消息協議的轉換,同時 MNS 也支持后臺邏輯服、工會、戰斗服之間的異步解耦拆分。
總結
對于 RocketMQ 來講,隨著核心架構經歷了五次重要的演進階段。RocketMQ 5.0
包含了非常多的新功能,這些功能在完善消息功能的同時,也帶來大量的概念和組件更新。
作為阿里云 RocketMQ 的輕量版,填補了 RocketMQ 在輕量化和易用性的不足。盡管 MNS 版本伴隨 RocketMQ 經過多年迭代與打磨,內部極為復雜,但一直努力保持其在客戶端的簡單易用。為企業和開發者降低消息產品的復雜度,減少運維開銷提供更易上手的消息隊列服務,是 MNS 的產品使命和愿景。
【MNS產品訓練營活動火熱報名中!】
為了幫助大家由淺入深的對阿里云消息隊列MNS有更加全面的了解,同時期望消息隊列MNS能夠幫助大家解決日常工作和生產的問題,特推出消息隊列MNS產品訓練營課程,課程中不僅有對產品簡單形象的介紹,還有“首秀”的動手實踐學習課程。
參與本次消息隊列MNS訓練營,您可以學習并收獲到:
- 消息隊列MNS的基礎概念及特性
- 消息隊列MNS的最佳實踐及案例
- 基于MNS,0基礎輕松構建Web Client
除了學習層面的收獲,活動期間,完成所有參營任務且考試通過的前20名同學可獲得(若成績相同按考試時間順序排名),即可免費獲得小米充電寶。活動時間:8月10日-8月31日(工作日期間)。
點擊鏈接,立即報名吧~??https://developer.aliyun.com/trainingcamp/1091392f83464404a407920226a9df17?utm_content=g_1000353774??

































