1. 程式人生 > >電商非同步訊息系統的實踐

電商非同步訊息系統的實踐

宣告:本文為《從程式設計師》7月期原創投稿文章,未經許可禁止任何形式的轉載。 
作者:王曉宇,小米網平臺研發部軟體研發工程師。2015年入職小米,主要負責電商後端倉儲物流相關的業務系統開發。曾在西門子中國研究院,從事軟體研發工作,擁有兩年以上的軟體開發相關經驗。曾使用過的程式語言主要有Java與PHP,擁有多年的伺服器開發經驗以及MySQL優化經驗,對電商相關業務與系統架構具有一定的瞭解以及自己的見解。 
責編:錢曙光,關注架構和演算法領域,尋求報道或者投稿請發郵件[email protected],另有「CSDN 高階架構師群」,內有諸多知名網際網路公司的大牛架構師,歡迎架構師加微信qshuguang2008申請入群,備註姓名+公司+職位。

摘要:本文首先介紹小米網系統架構的發展變化,然後介紹Notify系統的設計,最後介紹Notify系統的演化與升級變遷。希望能給各位的工作帶來一些啟發與指導。

為了適應業務的高速發展,小米網的系統架構經歷了很多次變更。在此過程中,為了給各個子系統解耦合,同時保證最終一致性原則的實現,我們建立了自己的非同步訊息系統—— 
Notify非同步訊息系統。

小米網架構發展

小米網的發展大致可以分為三個階段:初創階段、發展階段、完善階段。

1. 初創階段

當小米推出自己的第一部手機時,為了減少渠道成本,我們開始推行電商直銷的商業模式,與此同時,開始建設小米電商網站。最開始,小米的業務特點是:

  • SKU(商品品類)單一;
  • 訂單量巨大;
  • 瞬時訪問量巨大。

後兩點是在最初設計系統時完全沒有想到,因為當前我們並沒有預料到小米手機會如此受歡迎和供不應求。

在這個階段,快速上線是第一目標,因為團隊需要快速配合公司的手機銷售計劃。所以一開始小米網的架構設計比較簡單,並沒有考慮高併發和大資料的情況。當時系統從立項到上線僅兩個多月時間,並且只由三名工程師開發完成。

圖片描述

圖1 小米電商初期的系統架構

從圖中可以看出,系統架構只有兩個Web伺服器與一個DB伺服器,兩臺Web伺服器互為主備,所有的業務功能整合在一個系統中。當時的架構設計僅能支援簡單的電商功能,我們預測每年的手機銷量能到30萬就已經很好了。但是計劃永遠趕不上變化,很快小米電商就遇到了第一個大問題:系統耦合度很高,導致當搶購活動開始時,其他業務都會受到影響。

2. 發展階段

為了解決上面的問題,需要對小米網的架構進行修改,把各種業務系統拆成獨立的子系統。這一時期小米電商的系統架構發展的特點是:

  • 業務系統的拆分,小米負責處理搶購請求的大秒系統就是在這一階段誕生的,將搶購業務帶來的系統壓力完全隔離開來,確保在搶購活動時小米的其他業務可以不受影響;
  • 小米的系統結構SOA(面向服務的軟體結構)化,小米各系統之間的通訊採用介面方式來實現,甚至我們開發了一套通訊協議,叫做X5協議,來規範介面的開發與呼叫。

這一階段小米網的架構如下圖所示:

圖片描述

圖2 小米電商發展階段的系統架構

從圖2可以看出,前端與後端系統完全獨立出來,當前端進行搶購活動時,後端的客服、售後、物流三大服務系統不會受到任何影響。圖2中所列舉的子系統只是小米網中的一小部分較為主要的系統,還有很多業務沒有列舉出來。

這種系統架構可以確保系統之間不會受到影響,但是介面的穩定性就成了一個至關重要的問題。這種系統架構幾乎所有的介面都是同步介面,意思就是說一個業務呼叫這些介面如果不成功,業務也無法成功。如果出現網路問題或者介面BUG,就會導致大量業務失敗。但事實上,並非所有的介面都必須做成同步性的,有些業務比如訂單系統把訂單資訊發給倉儲系統生產,就對同步性的要求不是很高,可以考慮使用非同步方式來解決。為了解決這個問題,小米網架構下一步的演化就是建立一個非同步訊息佇列系統。

3. 完善階段

經過非同步訊息系統的引入,小米網的系統架構最終發生了變化,如圖3所示:

圖片描述

圖3 小米網的系統架構

從圖3可以看出,非同步訊息佇列成了一箇中心節點,幾乎所有的子系統都與它有單向或者雙向的互動。當一個業務需要呼叫一個介面時,如果他對實時性的要求不是特別高,就可以把訊息發到我們的非同步訊息佇列系統,然後他就可以完成這項業務,而之後的訊息投遞過程就完全交給訊息佇列系統來實現。經過這次調整之後,小米網基本實現了主要業務的非同步化,大大增加了系統的容錯性,因為所有投遞不成功的訊息都可以儲存在訊息佇列系統中等待下次投遞。

Notify訊息系統的設計

基於對上面業務變化的分析,小米網內部開始計劃建立自己的非同步訊息系統。我們對比了市面的幾款MQ軟體,最後決定以Redis佇列為基礎,開發自己的非同步訊息佇列系統,取名叫做Notify非同步訊息系統。

Notify訊息系統的設計需要解決以下幾個問題:

  • 如何接收訊息;
  • 如何儲存訊息;
  • 如何投遞訊息;
  • 對訊息的統計與監控。

我們採用介面的方式來接收業務系統的訊息,採用MySQL來儲存訊息,在訊息傳送時使用Redis佇列來儲存。

為了實現以上主要功能,為Notify系統設計了以下的資料結構。下面為五個最主要的資料表,以及重要的欄位:

  1. biz - 業務(生產者);

  2. receive - 接收者(消費者);

  3. biz_receive - 訂閱關係; 
    狀態欄位,表示訂閱關係的執行狀態,分為正常、暫停(接收訊息,但不傳送)、廢棄(不接收訊息)三種。 
    介面地址欄位。

  4. biz_msg - 業務訊息; 
    訊息體欄位。

  5. receive_msg - 投遞訊息; 
    傳送狀態欄位,分為四種狀態,待處理、待投遞、已投遞、丟棄。 
    傳送次數字段。

這裡需要提一下Notify系統的訊息分裂機制。考慮到有可能在一項業務執行過程中需要把訊息發給多個介面,Notify訊息在設計的時候引入了一個訊息分裂的概念。

圖片描述

圖4 Notify訊息設計中的三種訊息分裂情況

圖4分別列舉了訊息分裂的三種情況。首先第一種,在沒有訊息佇列時直接呼叫介面的情況,一個業務執行時如果要將一個訊息傳遞給不同的系統時,就需要呼叫不同的介面,並且這些介面還必須都返回成功,才能算這個業務執行成功。第二種情況是引入訊息佇列來處理這個問題的話,如是不進行分裂處理的話,S1需要把同一個訊息塞到不同的訊息佇列裡去。也就是要多次將訊息傳送給Notify系統。這樣設計雖然可以確保業務執行成功,但是卻不具備擴充套件性。假設我們新建立一個系統,也需要同樣的訊息,那麼就不得不回過頭來修改程式碼,關閉一個系統也是同理。所以第三種情況中我們設立了一個訊息分裂與訂閱的機制,業務執行時只需要把訊息投遞到Notify系統一次,而其他系統如果需要這個訊息,就可以在我們的Notify系統中設定訂閱關係,同樣的訊息就被複製成多個副本,然後被塞到多個不同的訊息佇列來投遞。這樣做既可以進一步提高業務執行的成功性,又使得業務具備可擴充套件性與可配置性。

圖片描述

圖5 Notify的架構設計

基於上面的一系列設計思想,最終形成了圖5中的結構設計圖,即Notify系統的最初設計圖。我們通過Api.notify介面,來收集業務系統的訊息,並存放在DB中。傳送訊息時,我們設立一個Maker元件,這個元件採用多程序執行方式,對每一個訂閱關係開啟一個程序,把訊息複製一個副本並放到對應的RedisMQ中。MQ的名稱就以biz-receive的對應id組合而成,方便查詢。然後,我們設立了一個Sender元件,Sender主要完成兩樣工作:一是把訊息傳送給對應的業務系統;二是把訊息放到Marker Queue中,來回寫訊息的狀態。如果訊息傳送成功了,就把訊息的狀態回寫成已投遞,如果傳送失敗,就把訊息狀態重新回寫成待處理,以便下一個週期再次投遞。然後我們又設立了一個Marker程式,來非同步的讀取Marker Queue裡的訊息來回寫狀態。這樣就完成了一個投遞週期,整個Notify系統就是通過這種方式源源不斷的將訊息投遞給各業務系統。

除了上面的主要結構外,在實現Notify時,還引入了以下幾個特性:

  1. 訊息分裂,如上文介紹過的一樣。

  2. 冷庫備份功能。隨著業務的擴充套件,DB中的訊息數也增長的很快,如果不對DB中的訊息做備份,會影響Notify本身的效能,以及統計功能的可用性。對於已經投遞成功的訊息來說,大部分情況下不會被用到,所以需要定期對訊息做遷移冷庫的操作。

  3. 為了保證傳送訊息的時效性,對Maker與Sender進行了多程序程式設計,每個程序負責一個訂閱關係的處理,可以獨佔一個MQ的控制權,我們通過這種方式來提高訊息傳送的時效性,確保關鍵業務訊息不會被阻塞。

  4. 訊息重發功能。如果訊息傳送失敗,會被Marker重新標記成待處理狀態,以進入下一次的投遞週期,同時訊息的發次數會加1。每次投遞都間隔一定的時間,當投遞次數超過一個閾值時,就不再投遞了。因為這個時候可能是由於業務系統的接口出了什麼問題,再嘗試投遞沒有任何意義,還會造成網路流量的浪費,影響其他系統的業務,所以停止繼續投遞。待介面問題修復後,我們再手動批量重推訊息。

  5. 採用非同步方式,在投遞週期中,也用到了非同步思想,這樣做也是為了加快訊息投遞的時效。

  6. 訊息可查詢。Notify為小米網的其他工程師提供了一個可以查詢訊息體及返回的地方,方便我們工程師除錯系統,定位bug。

Notify訊息系統的升級變遷

第一版Notify訊息系統設計的時候還存在著很多不足與考慮不周之處。隨著業務的發展,逐漸暴露出很多問題。小米網每年有兩大促銷活動,一個是天貓的雙十一活動,另外一個是小米自己的米粉節。這兩個節日,小米網的訂單量是呈爆發式的增長,而且每年的訂單量峰值都會有所增加。這對業務系統,尤其是作為中心節點的Notify系統來說,是一次巨大的衝擊。所以Notify訊息系統在最初設計的基礎經過了很多修改,並且於去年完成了一次大的重構,才達到了現在的處理能力,以目前的效能來看,小米網可以輕鬆經受住米粉節或雙十一的訂單量。

目前Notify系統主要的不足有以下幾點:

  1. 業務直接通過介面方式投遞訊息。如果網路出現不可靠的情況,直接投遞還是會有引起業務失敗的風險;
  2. 系統全部使用PHP來實現。做為一種指令碼語言,PHP還是有很多不足的地方,比如無法進行高效的運算;
  3. 採用單一MySQL例項。在資料量過大時會影響效能。

針對上面的這些不足,我們對Notify進行了一些重構。首先,對於接收訊息的功能,我們改為採用Agent代理的方式,來收集訊息。如圖6所示:

圖片描述

圖6 Notify採用Agent代理的方式

業務系統由原來的直接將訊息傳送給Notify,改為將訊息存在本地資料庫,然後由常駐記憶體的Agent代理來收集訊息,並將訊息傳送給Notify系統。如此以來,大大增加了業務的成功率,因為DB操作的可靠性遠大於網路操作。

對於PHP問題,我們則是採用Golang將關鍵的模組進行了重構。經過這次重構,主要模組的效能都有了很大的提升。與老版本對比,Api.Notify系統每臺Web伺服器接收訊息的能力提升了21倍,Marker服務處理能力提升了4倍,Sender服務處理能力提升了4倍。最終投遞週期中的各環節效能達到了圖7中所示:

圖片描述

圖7

針對單一MySQL例項問題,我們引入了MyCAT,MyCAT是阿里開發並維護的一款開源資料庫中介軟體,實現了MySQL的分散式儲存,提升了資料庫效能,並且MySQL例項數量動態可擴充套件,最重要的是MyCAT可執行MySQL語句,因此與MySQL幾乎無縫切換,開發成本小。

總結

本文主要介紹了小米網在實現非同步訊息佇列系統時所進行的實踐與探索,介紹了非同步訊息系統的設計經驗,為其他公司的實踐提供保貴經驗。

編輯推薦:架構技術實踐系列文章(部分):

2016年8月12日-13日,由CSDN重磅打造的網際網路應用架構實戰峰會運維技術與實戰峰會將在成都舉行,目前18位講師和議題已全部確認。兩場峰會大牛講師來自阿里、騰訊、百度、京東、小米、樂視、聚美優品、YY互娛、華為、360等知名網際網路公司,一線深度的實踐,共同探討高可用/高併發/高效能系統架構設計、電商架構、分散式架構、運維工具研發與實踐、運維自動化系統的構建、DevOps、雲上的運維案例分析、虛擬化技術、應用效能檢測與管理、遊戲行業的運維實踐等,將和與會嘉賓共同探討「構建更安全、更高效能、更穩定的架構和運維體系」等領域的話題與技術。【八折優惠中,點選這裡搶票,欲購從速。】

相關推薦

非同步訊息系統實踐

宣告:本文為《從程式設計師》7月期原創投稿文章,未經許可禁止任何形式的轉載。 作者:王曉宇,小米網平臺研發部軟體研發工程師。2015年入職小米,主要負責電商後端倉儲物流相關的業務系統開發。曾在西門子中國研究院,從事軟體研發工作,擁有兩年以上的軟體開發相關經驗。曾使用過的程

億級流量詳情頁系統實戰-緩存架構+高可用服務架構+微服務架構第二版視頻教程

class 全文檢索 ron pan 教程 ec2 dubbo sgx 技術經理 14套java精品高級架構課,緩存架構,深入Jvm虛擬機,全文檢索Elasticsearch,Dubbo分布式Restful 服務,並發原理編程,SpringBoot,SpringCloud

互融雲區塊鏈全程溯源系統:為企業和消費者解決信任難題!

img 不可 企業 終端 結構 市場價格 vpd type 分布 區塊鏈技術從誕生之初就被給予厚望,不同於虛無縹緲的炒空氣幣,區塊鏈本身就是大有可為的下一代互聯網技術。在所有的場景應用中,溯源防偽被認為是最有前景的,也是巨頭們爭奪區塊鏈技術落地的第一個領域。國內重點城市紛紛

行業運維實踐

客戶 title signature 互聯網 企業管理 tps ima back 領導力 電商行業運維實踐 ------------------------------------------------------------------今天先到這兒,希望對您技術領導力,

解密 Redis 助力雙十一背後秒殺系統

秒殺活動是絕大部分電商選擇的低價促銷、推廣品牌的方式。不僅可以給平臺帶來使用者量,還可以提高平臺知名度。一個好的秒殺系統,可以提高平臺系統的穩定性和公平性,獲得更好的使用者體驗,提升平臺的口碑,從而提升秒殺活動的最大價值。 本文討論如何利用 Redis 快取設計高併發的秒殺系統。 秒殺的特徵 秒殺活動對

或財務系統計算錢精度的問題

在財務系統中經常,國內最小是分,比如說一件東西0.58元,如果買一百件那應該是58元吧? 用php表示計算 <?php var_dump(0.58*100) ;//58 ?> 結果正確,但是在看一下,下面的結果,怎麼就變成57了呢? <?php var_dump(i

10、生鮮平臺-財務系統模組的設計與架構

前言:任何一個平臺也好,系統也好,掙錢養活團隊這個是無可厚非的,那麼對於一個生鮮B2B平臺盈利模式( 檢視:http://www.cnblogs.com/jurendage/p/9016411.html)而言, 其中財務模組無論是對於買家而言還是賣家而言都至關重要,老百姓對錢的看重是沒有經歷的人想不到的,一

9、生鮮平臺-推薦系統模組的設計與架構

業務需求:          對於一個B2B的生鮮電商平臺,對於買家而言,他需要更加快速的購買到自己的產品,跟自己的餐飲店不相關的東西,他是不關心的,而且過多無用的東西摻雜在一起,反而不便 於買家下單,使用者體驗也很差,嚴重的會因此丟了客戶。(客戶覺得太難

26、生鮮平臺-RBAC系統許可權的設計與架構

說明:根據上面的需求描述以及對需求的分析,我們得知通常的一箇中小型系統對於許可權系統所需實現的功能以及非功能性的需求,在下面我們將根據需求從技術角度上分析實現的策略以及基於目前兩種比較流行的許可權設計思想來討論關於許可權系統的實現。 1.1.     &nb

9、生鮮平臺-推薦系統模塊的設計與架構

key cnblogs strong his 功能 tin 很多 status 清單 業務需求: 對於一個B2B的生鮮電商平臺,對於買家而言,他需要更加快速的購買到自己的產品,跟自己的餐飲店不相關的東西,他是不關心的,而且過多無用的東西摻雜在一起,反而不便

26、生鮮平臺-RBAC系統權限的設計與架構

企業管理 table state 添加 編碼 rgw 影響 對數 建設 說明:根據上面的需求描述以及對需求的分析,我們得知通常的一個中小型系統對於權限系統所需實現的功能以及非功能性的需求,在下面我們將根據需求從技術角度上分析實現的策略以及基於目前兩種比較流行的權限設計思想來

億級流量詳情頁系統的大型高併發與高可用快取架構實戰

對於高併發的場景來說,比如電商類,o2o,門戶,等等網際網路類的專案,快取技術是Java專案中最常見的一種應用技術。然而,行業裡很多朋友對快取技術的瞭解與掌握,僅僅停留在掌握redis/memcached等快取技術的基礎使用,最多瞭解一些叢集相關的知識,大部分人都可以對快取技術掌握到這個程度。然而,

Flink視頻教程_基於Flink流處理的動態實時實時分析系統

分布 業務 電商分析 apr 進行 處理 密碼 教程 包括 Flink視頻教程_基於Flink流處理的動態實時電商實時分析系統 課程分享地址鏈接:https://pan.baidu.com/s/1cX7O-45y6yUPT4B-ACfliA 密碼:jqmk 在開始學習前給

React16+React-Router4 從零打造企業級後臺管理系統

第1章 課程介紹 本章整體介紹該課程的內容,讓同學們瞭解這個課程的特點和學習方法,以及後臺管理系統開發前的一些前置工作,如需求分析、技術選型和資料介面等。 第2章 課前知識儲備 本章介紹一些後面課程要用到的一些基礎知識,為後面的開發打下基礎,包括頁面載入過程、E

淘寶雙十一秒殺系統架構設計

前言 最近在部門內部分享了原來在電商業務做秒殺活動的整體思路,大家對這次分享反饋還不錯,所以我就簡單整理了一下,分享給大家參考參考 業務介紹 什麼是秒殺?通俗一點講就是網路商家為促銷等目的組織的網上限時搶購活動 比如說京東秒殺,就是一種定時定量秒殺,在規定的時間內

阿里雲Redis讀寫分離典型場景:如何輕鬆搭建秒殺系統

背景 秒殺活動是絕大部分電商選擇的低價促銷,推廣品牌的方式。不僅可以給平臺帶來使用者量,還可以提高平臺知名度。一個好的秒殺系統,可以提高平臺系統的穩定性和公平性,獲得更好的使用者體驗,提升平臺的口碑,從而提升秒殺活動的最大價值。 本次主要討論阿里云云資料庫Redis

平臺-財務系統模組的設計與架構

前言:任何一個平臺也好,系統也好,掙錢養活團隊這個是無可厚非的,那麼對於一個生鮮B2B平臺盈利模式( 檢視: 其中財務模組無論是對於買家而言還是賣家而言都至關重要,老百姓對錢的看重是沒有經歷的人想不到的,一句話說清楚了:一分錢也不能少。   買家或者賣家對財務模組的要求很簡單:

DevOps廣州站|認真地聊一聊大型零售及網站架構優化實踐

佩爾西科夫教授認為 要創造幸福的生活,就要先愛上醜陋 ▼ 你是否認為… 要實現高速的增長,就要愛上不可控的技術進步 ▼ UCloud DevOps Workshop系列活動廣州站 ▼ 邱宇煒,百聯全渠道 研發中心總經理 吳浩,要出發周邊CTO Y3,UCloud基礎雲端計算研發中心總監 ▼ 一起為

基於Flink流處理的動態實時實時分析系統

在開始學習前給大家說下什麼是Flink? 1.Flink是一個針對流資料和批資料的分散式處理引擎,主要用Java程式碼實現。 2.Apache Flink作為Apache的頂級專案,Flink集眾多優點於一身,包括快速、可靠可擴充套件、完全相容Hadoop、使

使用 Redis 搭建秒殺系統

背景 秒殺活動是絕大部分電商選擇的低價促銷、推廣品牌的方式。不僅可以給平臺帶來使用者量,還可以提高平臺知名度。一個好的秒殺系統,可以提高平臺系統的穩定性和公平性,獲得更好的使用者體驗,提升平臺的口碑,從而提升秒殺活動的最大價值。 本文討論雲資料庫 Redis 版快取設計高併發的秒殺系統。 秒殺的特徵