轻量消息队列(原 MNS)支持顺序消息的能力。本文将为您介绍其核心概念、与普通消息的区别、创建与使用方法、API使用说明,以及相关的限制与最佳实践。
功能定义
轻量消息队列(原 MNS)的顺序消息支持为同一分组内的消息提供先进先出(First-In-First-Out)的能力,从而实现业务场景中消息的顺序处理。
应用场景
顺序消息主要适用于对消息先后顺序有严格要求的业务场景:
订单状态流转
电商订单系统中,订单创建→支付→发货→确认收货等状态必须按时间顺序处理,确保业务状态的正确性。
金融交易处理
证券、股票交易系统中,对于出价相同的交易单,需严格按照先出价先交易的原则,下游处理订单的系统必须按照出价顺序来处理订单。
数据库同步
上游数据库执行增删改操作,将二进制操作日志作为消息传输到下游系统,下游系统按顺序还原消息数据,实现状态数据按序刷新,避免数据不一致。
业务日志记录
关键业务操作的日志记录需要严格按照时间顺序保存,便于后续审计和问题排查。
关键概念
MessageGroupId:消息分组标识。系统依据分组保证消息顺序:在同一
MessageGroupId
内,消息处理严格遵循有序原则;而不同分组则可并行处理。可见性超时(Visibility Timeout):消息在成功拉取后,在超时之前对其他消费者不可见,以免消息被多个消费者同时处理。如果消息未被确认删除,则在超时后,消息将重新变为可见。
组锁定机制:在顺序队列中,同一
MessageGroupId
的消息被拉取后,如果一直未被确认删除(即处于不可见状态),将会阻塞同一MessageGroupId
的后续消息,以确保严格的消费顺序。仅在当前消息被确认删除或可见性超时到期后,同一分组的下一条消息方可被拉取。
与普通消息的差异
顺序语义:
普通消息(普通队列/主题):尽力保证至少一次投递,默认不保证顺序。
顺序消息(顺序队列/主题):在同一
MessageGroupId
内,消息的消费顺序必须严格按照到达服务端的时间进行。先到达的消息应优先处理,后到达的消息必须在前面消息处理完成后才能进行消费。
并发模型:
普通消息:无分组限制,强调整体吞吐。
顺序消息:以
MessageGroupId
为并发单元,组内串行,组间并行。
消息要求:
顺序消息发送必须指定
MessageGroupId
(适用于队列与主题)。
快速开始
顺序队列(FIFO队列)
创建队列:
在左侧导航栏,选择 。
在顶部菜单栏,选择地域。
在队列列表页面,单击创建队列。
在创建队列面板,队列类型选择顺序队列,配置其他参数,然后单击确定。
发送消息:
使用
SendMessage
,必须携带MessageGroupId
,建议使用业务主键(如订单号)。若不携带
MessageGroupId
,将返回错误码FifoMissingMessageGroupId
。
接收与确认:
使用
ReceiveMessage
拉取,返回体包含MessageGroupId
,处理完成后调用DeleteMessage
确认。
顺序主题(FIFO主题)
创建主题:
在左侧导航栏,选择 。
在顶部菜单栏,选择地域。
在主题列表页面,单击创建主题。
在创建主题面板,主题类型选择顺序主题,配置其他参数,然后单击确定。
创建订阅:
建议订阅时选择顺序队列,以确保推送顺序,普通主题仅能订阅普通队列。具体操作请参见步骤三:创建订阅。
发布消息:
使用
PublishMessage
,必须携带MessageGroupId
。若不携带
MessageGroupId
,将返回错误码FifoMissingMessageGroupId
。
消费与确认:
在订阅的顺序队列侧使用
ReceiveMessage
拉取并通过DeleteMessage
确认,保持分组内顺序处理。
API使用说明
队列相关API
API 名称 | 参数说明 | 返回说明 |
CreateQueue-创建队列 | 入参
| 创建对应类型的队列。 |
GetQueueAttributes-获取队列属性 | 无特殊参数 | 返回队列信息,包含 |
ListQueue-列出指定阿里云账号下的所有队列 | 无特殊参数 | 返回队列列表,每个队列包含 |
主题相关API
API名称 | 参数说明 | 返回说明 |
CreateTopic-创建主题 | 入参
| 创建对应类型的主题。 |
GetTopicAttributes-获取主题的属性 | 无特殊参数 | 返回主题信息,包含 |
ListTopic-查询阿里云账号下的主题列表 | 无特殊参数 | 返回主题列表,每个主题包含 |
消息收发API
API名称 | 参数要求 | 返回说明 | 备注 |
顺序队列必须携带 | 标准返回。 | 用于向队列发送单条消息。 | |
顺序队列必须携带 | 标准返回。 | 用于向队列批量发送消息。 | |
顺序主题必须携带 | 标准返回。 | 用于向主题发布消息。 | |
无特殊参数。 | 返回体包含 | 用于从队列接收单条消息。 | |
支持 | 返回体包含 | 可能包含多个分组的消息,各分组内顺序保持不变。 |
使用限制
目前支持的地域包括华南1(深圳)、华东2(上海)、华东1(杭州),其它地域有对消息先入先出(FIFO)访问的需求,请提交工单。
必须携带分组:向顺序队列/主题发送消息必须携带
MessageGroupId
。类型匹配:
死信(DLQ):仅支持相同类型的消息绑定,即顺序消息只能绑定到顺序类型的死信队列,而普通消息则只能绑定到普通类型的死信队列。
订阅:普通主题只能订阅普通队列;建议采用顺序主题订阅顺序队列,以确保消息的顺序。
不支持Peek:顺序队列不支持调用查看消息的接口(PeekMessage)。
最佳实践
分组设计:
使用稳定且均匀分布的
MessageGroupId
(如订单号),避免少量热点分组成为性能瓶颈。对极端热点业务,考虑在业务层对分组做细分以提升并发度。
可见性超时:按实际处理时长设置,确保业务在超时前完成并确认,降低重复投递概率。
幂等与重试:对消费者实现幂等处理与重试机制,保障端到端一致性。
批量拉取:在保证单条处理时延的前提下,合理增大
numOfMessages
以提升吞吐。
常见问题
顺序如何界定?
同一MessageGroupId
内的消息严格按发送顺序到达并被处理;不同分组之间可以并行处理。
一定要传MessageGroupId
吗?
是。顺序队列/主题发送消息必须传入MessageGroupId
,否则无法保证顺序。
与普通队列/主题如何选择?
若业务依赖严格顺序(如同一订单的状态流转),请选择顺序队列/主题;若更关注总体吞吐与弹性且对顺序不敏感,可使用普通队列/主题。如需开始使用,请在控制台创建顺序队列/顺序主题,发送时携带MessageGroupId
,在消费端读取该属性并按需处理与确认。