順序消息可以保證消息的消費順序和發(fā)送的順序一致,即先發(fā)送的先消費,后發(fā)送的后消費,常用于金融證券、電商業(yè)務(wù)等對消息指令順序有嚴(yán)格要求的場景。本文介紹云消息隊列 RocketMQ 版順序消息的概念、適用場景、實現(xiàn)原理以及使用過程中的注意事項。

什么是順序消息

順序消息是云消息隊列 RocketMQ 版提供的一種對消息發(fā)送和消費順序有嚴(yán)格要求的消息。對于一個指定的Topic,消息嚴(yán)格按照先進(jìn)先出(FIFO)的原則進(jìn)行消息發(fā)布和消費,即先發(fā)布的消息先消費,后發(fā)布的消息后消費。

順序消息分為分區(qū)順序消息全局順序消息

分區(qū)順序消息

對于指定的一個Topic,所有消息根據(jù)Sharding Key進(jìn)行區(qū)塊分區(qū),同一個分區(qū)內(nèi)的消息按照嚴(yán)格的先進(jìn)先出(FIFO)原則進(jìn)行發(fā)布和消費。同一分區(qū)內(nèi)的消息保證順序,不同分區(qū)之間的消息順序不做要求。

  • 適用場景

    適用于性能要求高,以Sharding Key作為分區(qū)字段,在同一個區(qū)塊中嚴(yán)格地按照先進(jìn)先出(FIFO)原則進(jìn)行消息發(fā)布和消費的場景。

  • 示例
    • 用戶注冊需要發(fā)送驗證碼,以用戶ID作為Sharding Key,那么同一個用戶發(fā)送的消息都會按照發(fā)布的先后順序來消費。
    • 電商的訂單創(chuàng)建,以訂單ID作為Sharding Key,那么同一個訂單相關(guān)的創(chuàng)建訂單消息、訂單支付消息、訂單退款消息、訂單物流消息都會按照發(fā)布的先后順序來消費。

阿里巴巴集團(tuán)內(nèi)部電商系統(tǒng)均使用分區(qū)順序消息,既保證業(yè)務(wù)的順序,同時又能保證業(yè)務(wù)的高性能。

全局順序消息

對于指定的一個Topic,所有消息按照嚴(yán)格的先入先出(FIFO)的順序來發(fā)布和消費。

  • 適用場景

    適用于性能要求不高,所有的消息嚴(yán)格按照FIFO原則來發(fā)布和消費的場景。

  • 示例

    在證券處理中,以人民幣兌換美元為Topic,在價格相同的情況下,先出價者優(yōu)先處理,則可以按照FIFO的方式發(fā)布和消費全局順序消息。

說明 全局順序消息實際上是一種特殊的分區(qū)順序消息,即Topic中只有一個分區(qū),因此全局順序和分區(qū)順序的實現(xiàn)原理相同。因為分區(qū)順序消息有多個分區(qū),所以分區(qū)順序消息比全局順序消息的并發(fā)度和性能更高。

如何實現(xiàn)順序消息

全局順序消息和分區(qū)順序消息原理一樣,下文以分區(qū)順序消息為例介紹在云消息隊列 RocketMQ 版中如何保證消息收發(fā)的順序。順序消息1.0
云消息隊列 RocketMQ 版中,消息的順序需要由以下三個階段保證:
  • 消息發(fā)送

    如上圖所示,A1、B1、A2、A3、B2、B3是訂單A和訂單B的消息產(chǎn)生的順序,業(yè)務(wù)上要求同一訂單的消息保持順序,例如訂單A的消息發(fā)送和消費都按照A1、A2、A3的順序。如果是普通消息,訂單A的消息可能會被輪詢發(fā)送到不同的隊列中,不同隊列的消息將無法保持順序,而順序消息發(fā)送時云消息隊列 RocketMQ 版支持將Sharding Key相同(例如同一訂單號)的消息序路由到一個隊列中。

    云消息隊列 RocketMQ 版服務(wù)端判定消息產(chǎn)生的順序性是參照同一生產(chǎn)者發(fā)送消息的時序。不同生產(chǎn)者、不同線程并發(fā)產(chǎn)生的消息,云消息隊列 RocketMQ 版服務(wù)端無法判定消息的先后順序。

  • 消息存儲

    如上圖所示,順序消息的Topic中,每個邏輯隊列對應(yīng)一個物理隊列,當(dāng)消息按照順序發(fā)送到Topic中的邏輯隊列時,每個分區(qū)的消息將按照同樣的順序存儲到對應(yīng)的物理隊列中。

  • 消息消費

    云消息隊列 RocketMQ 版按照存儲的順序?qū)⑾⑼哆f給Consumer,Consumer收到消息后也不對消息順序做任何處理,按照接收到的順序進(jìn)行消費。

    Consumer消費消息時,同一Sharding Key的消息使用單線程消費,保證消息消費順序和存儲順序一致,最終實現(xiàn)消費順序和發(fā)布順序的一致。

注意事項

  • 同一個Group ID只對應(yīng)一種類型的Topic,即不同時用于順序消息和無序消息的收發(fā)。
  • 對于全局順序消息,建議消息不要有阻塞。同時運行多個實例,是為了防止工作實例意外退出而導(dǎo)致業(yè)務(wù)中斷。當(dāng)工作實例退出時,其他實例可以立即接手工作,不會導(dǎo)致業(yè)務(wù)中斷,實際工作的只會有一個實例。
  • 云消息隊列 RocketMQ 版服務(wù)端判定消息產(chǎn)生的順序性是參照單一生產(chǎn)者、單一線程并發(fā)下消息發(fā)送的時序。如果發(fā)送方有多個生產(chǎn)者或者有多個線程并發(fā)發(fā)送消息,則此時只能以到達(dá)云消息隊列 RocketMQ 版服務(wù)端的時序作為消息順序的依據(jù),和業(yè)務(wù)側(cè)的發(fā)送順序未必一致。

順序消息常見問題

  • 同一條消息是否可以既是順序消息,又是定時消息和事務(wù)消息?

    不可以。順序消息、定時消息、事務(wù)消息是不同的消息類型,三者是互斥關(guān)系,不能疊加在一起使用。

  • 順序消息支持哪些地域?

    支持云消息隊列 RocketMQ 版所有公共云地域和金融云地域。

  • 為什么全局順序消息性能一般?

    全局順序消息是嚴(yán)格按照FIFO的消息阻塞原則,即上一條消息沒有被成功消費,那么下一條消息會一直被存儲到Topic隊列中。如果想提高全局順序消息的TPS,可以升級實例配置,同時消息客戶端應(yīng)用盡量減少處理本地業(yè)務(wù)邏輯的耗時。

  • 順序消息支持哪種消息發(fā)送方式?

    順序消息只支持可靠同步發(fā)送方式,不支持異步發(fā)送方式,否則將無法嚴(yán)格保證順序。

  • 順序消息是否支持集群消費和廣播消費?

    順序消息暫時僅支持集群消費模式,不支持廣播消費模式。

TCP SDK示例代碼

TCP協(xié)議下的示例代碼請參見以下文檔:

HTTP SDK示例代碼