顺序消息

轻量消息队列(原 MNS)支持顺序消息的能力。本文将为您介绍其核心概念、与普通消息的区别、创建与使用方法、API使用说明,以及相关的限制与最佳实践。

功能定义

轻量消息队列(原 MNS)的顺序消息支持为同一分组内的消息提供先进先出(First-In-First-Out)的能力,从而实现业务场景中消息的顺序处理。

应用场景

顺序消息主要适用于对消息先后顺序有严格要求的业务场景:

  • 订单状态流转

    电商订单系统中,订单创建→支付→发货→确认收货等状态必须按时间顺序处理,确保业务状态的正确性。

  • 金融交易处理

    证券、股票交易系统中,对于出价相同的交易单,需严格按照先出价先交易的原则,下游处理订单的系统必须按照出价顺序来处理订单。

  • 数据库同步

    上游数据库执行增删改操作,将二进制操作日志作为消息传输到下游系统,下游系统按顺序还原消息数据,实现状态数据按序刷新,避免数据不一致。

  • 业务日志记录

    关键业务操作的日志记录需要严格按照时间顺序保存,便于后续审计和问题排查。

关键概念

  • MessageGroupId:消息分组标识。系统依据分组保证消息顺序:在同一MessageGroupId内,消息处理严格遵循有序原则;而不同分组则可并行处理。

  • 可见性超时(Visibility Timeout):消息在成功拉取后,在超时之前对其他消费者不可见,以免消息被多个消费者同时处理。如果消息未被确认删除,则在超时后,消息将重新变为可见。

  • 组锁定机制:在顺序队列中,同一MessageGroupId的消息被拉取后,如果一直未被确认删除(即处于不可见状态),将会阻塞同一MessageGroupId的后续消息,以确保严格的消费顺序。仅在当前消息被确认删除或可见性超时到期后,同一分组的下一条消息方可被拉取。

与普通消息的差异

  • 顺序语义:

    • 普通消息(普通队列/主题):尽力保证至少一次投递,默认不保证顺序。

    • 顺序消息(顺序队列/主题):在同一MessageGroupId内,消息的消费顺序必须严格按照到达服务端的时间进行。先到达的消息应优先处理,后到达的消息必须在前面消息处理完成后才能进行消费。

  • 并发模型:

    • 普通消息:无分组限制,强调整体吞吐。

    • 顺序消息:以MessageGroupId为并发单元,组内串行,组间并行。

  • 消息要求:

    • 顺序消息发送必须指定MessageGroupId(适用于队列与主题)。

快速开始

顺序队列(FIFO队列)

  • 创建队列:

    1. 登录轻量消息队列(原 MNS)控制台

    2. 在左侧导航栏,选择队列模型 > 队列列表

    3. 在顶部菜单栏,选择地域。

    4. 队列列表页面,单击创建队列

    5. 创建队列面板,队列类型选择顺序队列,配置其他参数,然后单击确定

      image

  • 发送消息:

    • 使用SendMessage,必须携带MessageGroupId,建议使用业务主键(如订单号)。

    • 若不携带MessageGroupId,将返回错误码FifoMissingMessageGroupId

  • 接收与确认:

    • 使用ReceiveMessage拉取,返回体包含MessageGroupId,处理完成后调用DeleteMessage确认。

顺序主题(FIFO主题)

  • 创建主题:

    1. 登录轻量消息队列(原 MNS)控制台

    2. 在左侧导航栏,选择主题模型 > 主题列表

    3. 在顶部菜单栏,选择地域。

    4. 主题列表页面,单击创建主题

    5. 创建主题面板,主题类型选择顺序主题,配置其他参数,然后单击确定

      image

  • 创建订阅:

    建议订阅时选择顺序队列,以确保推送顺序,普通主题仅能订阅普通队列。具体操作请参见步骤三:创建订阅

  • 发布消息:

    • 使用PublishMessage,必须携带MessageGroupId

    • 若不携带MessageGroupId,将返回错误码FifoMissingMessageGroupId

  • 消费与确认:

    • 在订阅的顺序队列侧使用ReceiveMessage拉取并通过DeleteMessage确认,保持分组内顺序处理。

API使用说明

队列相关API

API 名称

参数说明

返回说明

CreateQueue-创建队列

入参QueueType

  • normal(普通队列)

  • fifo(顺序队列)

创建对应类型的队列。

GetQueueAttributes-获取队列属性

无特殊参数

返回队列信息,包含QueueType 字段。

ListQueue-列出指定阿里云账号下的所有队列

无特殊参数

返回队列列表,每个队列包含QueueType字段。

主题相关API

API名称

参数说明

返回说明

CreateTopic-创建主题

入参 TopicType

  • normal(普通主题)

  • fifo(顺序主题)

创建对应类型的主题。

GetTopicAttributes-获取主题的属性

无特殊参数

返回主题信息,包含TopicType字段。

ListTopic-查询阿里云账号下的主题列表

无特殊参数

返回主题列表,每个主题包含TopicType字段。

消息收发API

API名称

参数要求

返回说明

备注

SendMessage

顺序队列必须携带MessageGroupId

标准返回。

用于向队列发送单条消息。

BatchSendMessage

顺序队列必须携带MessageGroupId

标准返回。

用于向队列批量发送消息。

PublishMessage

顺序主题必须携带MessageGroupId

标准返回。

用于向主题发布消息。

ReceiveMessage

无特殊参数。

返回体包含MessageGroupId

用于从队列接收单条消息。

BatchReceiveMessage

支持numOfMessages 参数。

返回体包含MessageGroupId

可能包含多个分组的消息,各分组内顺序保持不变。

使用限制

  • 目前支持的地域包括华南1(深圳)、华东2(上海)、华东1(杭州),其它地域有对消息先入先出(FIFO)访问的需求,请提交工单

  • 必须携带分组:向顺序队列/主题发送消息必须携带MessageGroupId

  • 类型匹配:

    • 死信(DLQ):仅支持相同类型的消息绑定,即顺序消息只能绑定到顺序类型的死信队列,而普通消息则只能绑定到普通类型的死信队列。

    • 订阅:普通主题只能订阅普通队列;建议采用顺序主题订阅顺序队列,以确保消息的顺序。

  • 不支持Peek:顺序队列不支持调用查看消息的接口(PeekMessage)。

最佳实践

  • 分组设计

    • 使用稳定且均匀分布的MessageGroupId(如订单号),避免少量热点分组成为性能瓶颈。

    • 对极端热点业务,考虑在业务层对分组做细分以提升并发度。

  • 可见性超时:按实际处理时长设置,确保业务在超时前完成并确认,降低重复投递概率。

  • 幂等与重试:对消费者实现幂等处理与重试机制,保障端到端一致性。

  • 批量拉取:在保证单条处理时延的前提下,合理增大numOfMessages以提升吞吐。

常见问题

顺序如何界定?

同一MessageGroupId内的消息严格按发送顺序到达并被处理;不同分组之间可以并行处理。

一定要传MessageGroupId吗?

是。顺序队列/主题发送消息必须传入MessageGroupId,否则无法保证顺序。

与普通队列/主题如何选择?

若业务依赖严格顺序(如同一订单的状态流转),请选择顺序队列/主题;若更关注总体吞吐与弹性且对顺序不敏感,可使用普通队列/主题。如需开始使用,请在控制台创建顺序队列/顺序主题,发送时携带MessageGroupId,在消费端读取该属性并按需处理与确认。