严格保序队列__最佳实践_消息服务-阿里云
问题背景
阿里云消息服务提供的队列(queue)主要特点是高可靠、高可用、高并发。每个队列的数据都会被持久化三份到阿里云的飞天分布式平台;其中每个队列至少有2台服务器向外提供服务;同时每台服务器都支持高并发访问。这些分布式特性,也导致了消息服务队列无法像传统单机队列那样保证严格的消息FIFO特点,只能做到基本有序。
我们的队列如果同时有多个消息发送者(sender),由于并发和网络延迟不一等问题,消息的严格顺序本身就是失去了意义,因为在这种情况下,我们根本无法获知消息在多个sender上的实际发送顺序和消息到达服务器端的真实顺序。同样的,当有多个接收者并发接收消息时,其真正的处理顺序也是不可获知的。
因此,我们认为只有一个发送者(一个进程,可以是多个线程), 一个接收者时,消息顺序才有意义,也只有在这种情况下我们能够感知和记录消息的真实发送顺序和消息的真实接收顺序。
解决方案
基于上述假设,同时为了满足部分用户对于消息消费顺序性的要求,我们设计了下面的方案,确保消息按照用户发送顺序被接收和消费。
主要步骤:
消息在发送端进行染色,加上SeqId(例如:#num#)
消息在接收端进行还原,并根据SeqId 排序后返回给上层,同时对于已经receive的消息会有后台线程保证消息不会被重复消费。
为了避免因为发送者fail,或者接收者fail,导致seqid 丢失。seqid 会被持久存储到本地磁盘文件。(当然也可以存储到其他存储或数据库:例如OSS,OTS,RDS)
程序说明
附件提供了python版的方案实现(依赖MNS Python SDK)。其中,主要提供了OrderedQueueWrapper 类(oredered_queue.py文件),可以将普通的mns queue包装成有序queue。
OrderedQueueWrapper 提供两个方法:SendMessageInOrder()和ReceiveMessageInOrder()。send中对消息进行染色,receive还原消息,并且按顺序返回给接收者。
另外,send_message_in_order.py和receive_message_in_order.py提供了发送者和接收者使用OrderedQueueWrapper的程序示例。
send_message_in_order.py:
#init orderedQueue
seqIdConfig = {"localFileName":"/tmp/mns_send_message_seq_id"} # 指定持久化发送SeqId的磁盘文件。
seqIdPS = LocalDiskStorage(seqIdConfig)
orderedQueue = OrderedQueueWrapper(myQueue, sendSeqIdPersistStorage = seqIdPS)
orderedQueue.SendMessageInOrder(message)
receive_message_in_order.py:
#init orderedQueue
seqIdConfig = {"localFileName":"/tmp/mns_receive_message_seq_id"} #指定持久化接收SeqId的磁盘文件
seqIdPS = LocalDiskStorage(seqIdConfig)
orderedQueue = OrderedQueueWrapper(myQueue, receiveSeqIdPersistStorage = seqIdPS)
recv_msg = orderedQueue.ReceiveMessageInOrder(wait_seconds)
运行方法:
1.配置send_message_in_order.py 和receive_message_in_order.py 中下列配置项g_endpoint,g_accessKeyId,g_accessKeySecret,g_testQueueName
2.运行send_message_in_order.py
3.运行receive_message_in_order.py (可以不用等步骤2程序运行完成)发送程序会发送20条消息,接收程序会按顺序消费20条消息
也可以运行oredered_queue.py (需配置endpoint 和AK)的测试case对比普通mns queue的区别:
运行命令:$python oredered_queue.py
非严格有序:(整体有序,部分相邻消息无序,同时侧面证明MNS 的单个queue同时有多个服务器在提供服务)
严格有序:
注意事项:
1.本帖主要目的是展示顺序消息的解决方案,本帖中的代码未经过严格测试,不建议不加测试直接用于生产环境。同时程序仓促完成,难免由瑕疵,欢迎回帖指正。
2.正常情况下,发送端和接收端的seqid应该和queue中的消息(染色)匹配,当出现删除queue重新创建等操作时,请注意磁盘文件中的seqid 是否和queue中的真实情况相符,同时建议不要往染色的消息队列里发送非染色消息。
3.队列的消息有效期设置过短或者每条消息的实际处理结果都有可能会对消息有序性造成影响,在您的程序中需要对这些情况所导致的的乱序现象进行处理。
示例程序下载:
最后更新:2016-11-23 17:16:08
上一篇:
消息加密传输__最佳实践_消息服务-阿里云
下一篇:
超大消息传输__最佳实践_消息服务-阿里云
可用类型__控制台使用指南_批量计算-阿里云
MergeShards__日志库相关接口_API-Reference_日志服务-阿里云
DomainLogType__数据类型_API文档_云解析-阿里云
1.5 镜像部署环境__ECS快速开始_云服务器ECS 体验_体验馆-阿里云
郡县图治简介__郡县图治_数据可视化-阿里云
阿里云汇聚畅捷通等合作伙伴开启智能“大航海时代”!轻公司方能弄潮新经济!
运行SQL__快速开始_大数据计算服务-阿里云
金融云特性__金融云介绍_金融云-阿里云
阿里云发布自研商用关系型数据库POLARDB
为什么云数据库 HybridDB 版的 OLAP 性能比 RDS 好?__使用管理常见问题_产品相关问题_云数据库 HybridDB-阿里云
相关内容
常见错误说明__附录_大数据计算服务-阿里云
发送短信接口__API使用手册_短信服务-阿里云
接口文档__Android_安全组件教程_移动安全-阿里云
运营商错误码(联通)__常见问题_短信服务-阿里云
设置短信模板__使用手册_短信服务-阿里云
OSS 权限问题及排查__常见错误及排除_最佳实践_对象存储 OSS-阿里云
消息通知__操作指南_批量计算-阿里云
设备端快速接入(MQTT)__快速开始_阿里云物联网套件-阿里云
查询API调用流量数据__API管理相关接口_API_API 网关-阿里云
使用STS访问__JavaScript-SDK_SDK 参考_对象存储 OSS-阿里云