轻量消息队列(原 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,在消费端读取该属性并按需处理与确认。