944
阿裏雲
嚴格保序隊列__最佳實踐_消息服務-阿裏雲
問題背景
阿裏雲消息服務提供的隊列(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-阿裏雲