<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    本文原文內容引用自高可用架構公眾號,內容有整理和修訂。

    1、引言

    大家對下面這個排隊的場景應該非常熟悉,這個是小米手機搶購的用戶排隊交互圖,大家看到這些排隊的兔子時,說明也有很多用戶在同一時間向小米搶購系統提交了購買請求。

    ▲ 小米手機搶購排隊中...

    小米搶購系統后端服務面臨巨大的壓力,下圖可以反映小米搶購系統面臨的瞬間峰值壓力。這張圖截取自某年米粉節大秒服務后端其中一組LB(負載均衡層)的每分鐘請求總數的情況(橫軸的時間是UTC時間),如大家可以想象到的一樣,峰值流量是普通情況下流量的近10倍。

    ▲ 某年米粉節大秒服務后端其中一組負載均衡層的QPS統計情況

    以上就是小米搶購活動時后端服務集群面臨的壓力。小米搶購系統從2011年底誕生到成長為一個扛過2次米粉節和多次爆品首發的高性能、高可靠的峰值系統,經歷了很多次大大小小的架構演進,本次分享將為大家解密該系統的技術演進、設計思路、實踐總結等,希望能帶給您啟發。

    (本文同步發布于:http://www.52im.net/thread-2323-1-1.html

    2、分享者

    馬利超:小米科技的系統研發與大數據工程師,2013年畢業于大連理工大學,畢業后有幸加入小米搶購系統團隊,并參與了小米搶購系統開發、重構與調優。其人熱愛技術,對分布式系統架構、高并發峰值系統、大數據領域、反作弊領域、搜索/廣告/推薦系統有濃厚的興趣。

    3、相關文章

    新手入門:零基礎理解大型分布式架構的演進歷史、技術原理、最佳實踐

    達達O2O后臺架構演進實踐:從0到4000高并發請求背后的努力

    騰訊資深架構師干貨總結:一文讀懂大型分布式系統設計的方方面面

    快速理解高性能HTTP服務端的負載均衡技術原理

    子彈短信光鮮的背后:網易云信首席架構師分享億級IM平臺的技術實踐

    知乎技術分享:從單機到2000萬QPS并發的Redis高性能緩存實踐之路

    4、小米搶購系統的前世今生

    4.1 早期的架構設計

    2011底,在小米手機首批30萬全部發完貨之后,接下來便是大家熟知的,每周二中午十二點,小米手機開放購買。在開放購買期間,海量的用戶請求瞬間沖擊過來,對于當時小米這樣一個初創公司,特別是一個剛成立不到半年的電商團隊來說,面臨的挑戰是巨大的。

    面臨的問題大致如下:

    1)第一次開放購買,在小米商城主站進行,在瞬時壓力下,整個主交易系統并沒有逃脫掛掉的命運;

    2)開放購買活動是結束了,但是一周之后,下一輪的開放購買已經開始開放預約,開放購買又會如期而至。

    為了保證下次開放購買順利進行,留給小米網工程師團隊的時間是有限的,只有短短的7天時間。

    經過技術團隊討論,為了避免搶購時的峰值流量壓垮整個小米網,決定設計一套獨立的搶購系統。預約用戶通過在這套獨立的搶購系統中搶到購買資格,購買資格會異步的由資格數據同步模塊同步到用戶的購物車中,從用戶搶到手機那一時刻起,在規定的時間內,用戶小米商城完成下單和支付。

    從此這版獨立的搶購系統承接了小米的所有的搶購,經歷過大大小小的優化與重構,最后又演化為整個小米網的限流峰值系統。這版最初的搶購系統內部代號:TD。

    這套系統早期的架設設計出發點是:

    1)并發能力要盡量的高,能承受瞬時的峰值;

    2)不能超賣(可容忍小量的超賣);

    3)只有預約用戶可以購買,一個用戶只能買一臺;

    4)要非??煽浚徺I記錄不可丟失。

    TD的早期技術架構圖:

    如上圖所示,小米第一版搶購系統使用的技術棧:LVS + nginx + PHP + node.js + redis:

    1)預約用戶信息緩存在遠端緩存集群中,一主多從結構,具體在放號的過程中,對預約數據只有查詢操作;

    2)放號業務邏輯層使用PHP開發(當時小米網PHP開發者居多),使用遠端緩存作為數據中心,存放用戶的購買記錄,同時,每放一個資格號,記錄一條持久化的log(資格日志),保障用戶購買記錄可靠;

    3)使用node.js開發的資格日志收集及統計模塊logagent,收集資格日志,并將資格日志發送到遠端的logserver;同時,logagent統計自己所在的機器上購買記錄的條數,由于事先均等的分配好每臺機器的商品銷售數量,當機器上購買成功的日志條數大于等于分配的數量時,則在本地生成一個.Lock的文件;

    4)PHP開發的放號業務邏Middle集群中服務可能會輯中首先會檢查.Lock的文件是否存在,來標志這臺機器上的資格數是否被放完;同時,logserver將用戶購買成功的資格同步到購物車及其他相關服務系統中。

    這套架構的回顧和總結:

    1) 伸縮性強:PHP開發的放號邏輯不持有狀態數據,狀態數據存在遠端數據中心或者由logagent控制生成本地文件鎖(.Lock)標識,伸縮性強;

    2) 可靠性高:搶購成功記錄以日志的形式記錄,保障數據可靠性。

    該系統經過不間斷的優化,滿足了2012年及2013年上半年的搶購需求,應對的預約量在100萬級別。

    毫無疑問,這個初期架構也存在很多問題:

    1)單機處理能力有限:由于單機處理能力有限,如果要應對千萬級別的預約量時,假設不暴漏伸縮性問題的話,需要的資源數量是否能承擔的起?

    2)logserver處理能力: logserver的管理能力有限,隨著搶購人數的增多,并發量的增加,當前邏輯下,每秒放的資格數量會增加,logserver是否能夠及時的處理這些資格記錄?

    基于上述問題,接下來我們來看小米新一代搶購系統,也可以理解為加強版。

    4.2 加入了限流服務后的新一代搶購系統

    2013年7月份,小米發布了紅米手機,并與QQ空間合作首發,1分鐘內預約達到30萬,半個小時預約量達到100萬,72小時預約量突破500萬,小米手機的預約量從此進入了千萬級別,面對如此驚人的預約量,像之前分析的那樣,如何在短時間內應對這個突發的量級變化呢?(紅米手機發布前,技術團隊并不清楚將要面臨的挑戰)。

    經過技術團隊討論之后,決定在搶購系統之前加一層限流服務,將流量限制在TD能夠處理的能力范圍之內,由此便演進出一個新的服務——限流服務,內部代號: TC。

    新一代搶購系統的整體架構介紹如下:

    最初的TC使用nginx+Lua開發,主要負責用戶預約驗證和每秒向后端放行流量控制:

    1)TC在活動開始前,load預約用戶數據到nginx共享內存中;

    2)使用Lua開發每秒放量計數邏輯,nginx的異步IO機制加上Lua的多協程處理能力,使限流層能夠達到一個很高的并發量;

    3)Nginx是多進程運行,我們需要將預先限流層的每秒放行總量均攤到整個Nginx集群的進程數量上,而非按照機器數量均攤。

    TC與TD之間以token的形式交互,用戶從TC上取得放行資格,然后拿著這個資格去TD放量集群中請求放量,TD放行通過,才代表最終的搶購成功。

    有了上述的系統結構,只要放行控制得當,再高的流量壓力也不用怕了,我們也成功撐過了紅米首發。

    從此這個小米開放購買預約量進入了千萬級別,紅米2首發預約量更是在兩千萬級別。

    盡管系統并發能力有了大大的提升,但是整個系統仍有一些不足:

    1)管理功能簡陋:活動過程中需要人工干預活動的結束,在TD服務將商品賣完后,手動執行命令設置TC內存中指定商品的銷售狀態為售罄,這個誤操作風險非常高,并且延遲很高,在商品售罄后不能及時的通知用戶售罄狀態;

    2)靈活性較弱:技術團隊對于lua使用還不夠靈活,TC也只能處理一些簡單的業務邏輯;

    3)反應能力不足:前后端處理能力差距較大,一旦限流失誤,后端很快就會崩潰,管理體系的不完善,不能瞬時響應。往往在流量高峰下,再多1秒的請求量,就有可能使整個系統發生雪崩。反應能力的不足造成,系統的可靠性下降。

    在TC限流服務優化的過程中,我們調研了其他高并發的語言,如: C/C++、 scala、erlang、node.js、golang等。

    從學習成本、開發效率、運維便捷性等多方面評估,我們選擇使用golang開發了一版TC服務。在2013年11月,我們上線了golang版的TC服務,同時也針對這款golang版的TC限流服務和TD放號服務開發了統一的監控管理平臺,由監控管理平臺統一協調整個活動以及參與活動的商品的配置與狀態,在整個系統流程上保證了很好的連貫性以及運營的靈活性。監控管理平臺同時還負責監控各個服務的運行狀態,及時報警。

    接下來的文章內容,我們將詳細介紹基于golang的小米搶購系統(內部稱為“大秒”),也是本文的分享重點,請繼續往下閱讀。

    5、整合了搶購限流峰值服務后的小米搶購系統:“大秒”

    接上節,我們繼續詳細介紹這套最新架構。

    時間回到2014年初,當時公司決定舉辦一場“米粉節”活動,全天6輪活動,多個國家、多款爆品同時參與搶購。業務場景將變得更加復雜,當天的并發壓力也會有一個量級的提升,原有的搶購系統已經不能適應如此復雜的業務場景了。

    為此,小米網技術團隊基于對 golang 應對高并發、大規模分布式系統能力的肯定,完全基于 golang,重新設計了搶購系統,也就是我們目前使用的搶購限流峰值系統——“大秒”。

    在整個系統設計的之初,我們充分考慮了:

    1)靈活性及可運營性;

    2)可運維性及可伸縮性;

    3)限流與搶購放號的精準性。

    從大秒第一天誕生到演化至今有很多次重構與優化,但一直沿用了設計之初的結構,接下來我們詳細了解下這套架構的技術設計以及填過的一些坑。

    6、“大秒”系統的架構設計

    大秒系統主要由如下幾個模塊構成:

    1)限流集群 HTTP 服務;

    2)放號策略集群 Middle 服務;

    3)監控數據中心 Dcacenter;

    4)監控管理體系 Master;

    5)準實時防刷模塊 antiblack;

    6)基礎存儲與日志隊列服務:Redis 集群、Kafka 集群等。

    整個大秒體系中大秒前端模塊 (HTTP/middle/antiblack) 和監控數據中心使用 golang 開發,大秒監控管理體系使用 Python + golang 開發。

    7、“大秒”的前端架構設計

    “大秒”前端的架構設計從三個系統展開:

    1)限流集群 HTTP 服務;

    2)策略集群 Middle 服務;

    3)準實時反作弊 antiblack 服務。

    7.1 限流集群 HTTP 服務

    搶購高峰時,通常會有幾百萬的用戶同時請求,瞬時流量非常大,HTTP 集群頂在最前線,接受用戶的請求,將合法的請求發送的處理隊列,處理隊列設置一定的長度限制,通常情況下,搶購用戶數與銷售商品的比例在100:1,甚至更高,為了避免系統不被沖垮,保障絕大多數用戶的體驗,我們認為流量是部分可丟失的,當處理隊列滿時,丟棄入隊請求;

    雖然設計上過載流量是部分可丟棄的,但是策略層處理能力是非常 power 的,即便是需要丟棄流量,也是按流量的惡意程度,逐級丟棄的,正常用戶購買請求不受影響。

    我們使用基于規則的識別、離線畫像信息、機器學習邏輯回歸等方法,識別惡意用戶,在系統高負載的情況下,這部分請求可以優先阻擊其發送到策略層,優先處理正常用戶的請求,保障用戶體驗過。

    HTTP集群中不同節點之間的所持用的狀態數據是一致的,處理邏輯也是一致的,所以整個集群中的任何一個節點掛掉,在前端負載均衡能力下,服務的準確性與一致性不受任何影響。

    7.2 策略集群 Middle 服務

    HTTP 模塊將滿足條件用戶的請求按照 uid 哈希的規則,轉發到 Middle 集群中相應的節點,Middle 集群根據商品放號策略判斷 (uid:sku:time) 組合是否可以分配購買資格,并返回給相應的 HTTP 服務;

    使用 Middle 服務本地內存維護用戶的購買記錄信息,支持各種購買規則,比如:單次活動不限購買數量,單次活動僅限購買一款商品,單次活動每款商品僅限購買一次。

    我們將 Middle 的放號邏輯抽象成一個有限狀態機,由商品的放號策略配置閾值來觸發放號狀態轉換,整個配置由 Master 節點統一管理與調度。

    為了提升整個系統的處理能力,我們將用戶狀態數據局部化,單用戶(uid)的所有相關信息全部路由到一臺 Middle 節點上處理。

    但是有一點風險是,Middle 集群中服務可能會出現活動過程中掛掉的風險,在搶購場景下,商品基本上是瞬時賣完,為了保障系統的處理能力,我們主要從代碼層面做優化,review 代碼邏輯,保證服務應對異常的處理能力。

    雖然理論上存在風險,但是在實際工程中,經歷過幾百次活動,還沒出現 Middle 節點掛掉的情況。

    7.3 準實時防刷 antiblack 服務

    基于日志流的防刷架構,在每臺 HTTP 節點上部署日志收集 Agent,使用高吞吐量的 Kafka 做日志轉儲隊列,antiblack 模塊實時分析用戶請求日志,基于 IP 粒度、Uid 粒度等做防刷。

    雖然此處將 antiblack 模塊定義為準實時防刷模塊,但是作弊信息識別的延遲時長在 1 分鐘之內,其中主要的時延發生在日志的轉儲過程中。

    8、“大秒”的監控管理體系

    8.1 監控數據中心 dcacenter

    1)監控數據中心數據種類:

    1)業務級數據:過大秒的商品配置數據與實時狀態數據,當前活動的配置與狀態數據等;

    2)系統級數據:大秒前端服務集群通信地址配置,限流隊列初始長度配置,系統服務資源占用情況,包括:CPU、MEM、連接數等;

    2)數據采集方式:

    同時使用push和pull模式采集業務級監控數據和系統級監控數據,業務級數據越實時越好,做到1秒采集處理,3秒可視化;對于 HTTP 節點和 Middle 節點采用pull的模式拉去系統監控數據和業務監控數據。

    具體的優點如下。

    a. 靈活性高:

    由數據中心控制監控數據采集的粒度,在數據中心處理能力既定的情況下,可以根據前端集群的伸縮規模,靈活的調整數據采集的粒度,比如米粉節時,大秒前端集群擴容至過百臺,管理的過大秒商品的數量在400個左右,業務級監控數據量很大,此時監控數據采集時間間隔很容易降配至 2s。

    對于除Http服務和Middle服務之外的服務集群,如:redis,管理平臺各個模塊等可以使用監控數據采集agent,將采集到的數據周期性的push到redis隊列,dcacenter采集協程實時的從redis隊列中拉去消息,對于基礎服務以及python實現的服務,增加了監控數據采集靈活性。

    b. 增強服務的可靠性與伸縮性:

    大秒在設計之初采用push的方式,在每臺前端機器上部署一個數據采集agent,agent和大秒前端服務同時alive,才代表搶購系統健康運行。這樣即增加了系統的不穩定因素,由不利于系統的伸縮,將監控數據采集邏輯內置到前端golang程序中,提供tcp管理端口,在數據中心使用pull方式采集數據,很好的解決了這個問題。減少了服務的數量,增強了整個系統的可靠性與伸縮性。

    3)數據ETL與數據緩存:

    dcacenter同時負責將采集到的業務級數據及系統級監控數據,實時清洗,提取,轉換,結構化,并將結構化的數據存儲在自身內存中,定制通信協議(golang實現類redis通信協議),作為一個數據中心,對整個管理體系Master及其他系統提供實時數據支持。

    將dcacenter直接作為數據中心,主要是出于數據的實時性考慮,省去中間轉儲環節,上層可視化系統、自動化活動控制系統、規則引擎系統等可以第一時間獲得前端實時的銷售狀態數據及服務的狀態數據。

    8.2 監控管理中心 Master

    監控管理中心的主要模塊如下。

    a.倉儲庫存同步服務StockKeeper:

    同步商品的倉儲系統中的實時庫存到秒殺系統,大秒系統擁有雙庫存保障,一個是實時倉儲庫存,一個是虛擬庫存也就是資格號,在搶購場景下只有當兩個庫存都有貨時,才能正常銷售。

    b.商品策略控制器PolicyKeeper:

    基于相應的策略觸發器(時間區間與庫存區間),當策略觸發時,比如12點整,搶購開始,為相應的商品配置策略,并向大秒前端廣播商品配置變更命令,在通信基礎模塊的保障下,整個過程秒級內完成。

    c.活動自動化控制ActKeeper:

    基于監控數據中心獲取大秒前端的實時銷售數據,自動化的控制活動中的各個狀態,活動開始前逐層打開開關,活動開始時打開最后開關,活動過程中維護活動的售罄狀態,活動結束后初始化,整個搶購活動的過程無需人工介入;

    d.數據可視化:

    從監控數據中心提取實時的結構化系統級監控數據和業務級監控數據,將活動過程中的詳細數據實時可視化到管理頁面上,讓運營與銷售以及大秒管理員能夠及時了解當前活動狀態,并人工干預活動;

    e.監控規則引擎:

    監控規則引擎建立在監控數據中心之上,根據結構化監控數據判斷當前整個搶購系統的狀態,及時報警,以及半自動化控制。

    f.其他:

    大秒管理端管理大秒前端所有的數據、配置以及狀態,Master體系提供了詳細的管理工具與自動化服務。如果清理大秒前端Middle服務中的用戶購買信息等。

    8.3 大秒配置管理數據流

    整個搶購系統由 Master 體系中各個服務做統一的控制的,Master 控制商品狀態及配置數據的變更,控制當前活動的狀態,控制商品放號的策略等。

    為了保證時效性,商品、活動、系統等配置狀態的變更都需要將變更命令廣播前端集群,這期間發生了大量的分布式系統間通信,為了保障命令及時下行,我們提取出了命令轉發服務:MdwRouter,用于廣播控制命令到大秒前端集群。該服務模塊維護了到大秒前端長連接,接收 Master 下發的控制命令,并瞬時廣播,保障了整個控制流的處理能力。

    舉個例子:

    某年米粉節,我們單機房大秒集群的規模在過百臺級別,假設為 100 臺,管理的獨立的商品id的數量在 400 個左右,在這種量級的活動下,商品的放行策略是批量管理的,比如我們根據后端交易系統的壓力反饋,調整所有商品的放行速度,這時候需要廣播的命令條數在: 100*400=40000 級別,Mdwrouter 很好的保障了系統命令下行的速度,秒級完成命令下行。

    9、小米搶購技術架構整體概覽

    9.1 整個搶購服務閉環設計

    ▲ 整個小米網搶購系統服務閉環

    整個小米網搶購系統服務閉環如上圖所示:

    1)bigtap體系中大秒前端服務負責搶購時限流放號,并控制放號策略以及維護用戶在本地緩存中的購買記錄;

    2)cart服務驗證token的有效性,并向counter服務發起銷量驗證請求;

    3)counter服務是整個搶購系統最終的計數器, 海量的請求在bigtap服務的作用下已經被限制在可以承受的壓力范圍內,并且復雜的放號策略已經在大秒Middle服務中實現,counter只負責最終的計數即可。counter服務采用redis記錄相應商品的放號情況,根據預設的銷量,判斷當前請求加購物車商品是否有庫存余量,并維護商品銷量;

    4)bigtap體系中的dcacenter服務實時采集商品銷量,Master中活動自動化控制服務依據商品銷量判斷當前商品是否售罄,售罄則通過設置商品的售罄狀態,并通知大秒前端。

    9.2 整個系統在2015年米粉節的實際應用情況

    從上述整個服務閉環設計可以看出,“大秒”的功能完全可以抽象成限流系統,只有在處理搶購活動時,數據的管理與一致性要求才使整個系統變得復雜。

    2015年米粉節,我們完全使用大秒的限流功能,不限用戶的購買數量,很便捷的將系統部署在兩個機房,一個物理機房,一個公有云集群,兩者同時服務,大秒系統作為整個商城的最前端,能夠根據后端服務的壓力狀態,瞬時調整整個集群放行流量大小,非常好的保障了整個米粉節的正常舉行。

    正如您看到在上述文章中介紹的那樣,這些服務設計的每一次優化的背后,都至少有一次慘痛的經歷,針對這些經歷,我們也做了大量的總結,這些總結將在下兩節的內容里進行總結性地分享。

    10、“大秒”系統架構的幾點經驗總結

    10.1 Golang GC 優化方法

    我們從 golang 1.2 版本開始在線上搶購系統中大規模使用,最初上線的 TC 限流集群在搶購的過程中通過過載重啟的方式瘸腿前行。

    在當前的大秒系統中,對于限流集群主要是 goroutine 資源、HTTP 協議數據結構、TCP 連接讀寫緩沖區等頻繁動態開銷,造成內存 GC 壓力大。

    在現有 GC 能力下,我們對 GC 優化從以下幾個方面考慮:

    1)減少垃圾產生:降低數據結構或者緩沖區的開銷;

    2)手動管理內存:使用內存池,手動管理內存;

    3)臟數據盡快釋放,增大空閑內存比。

    我們使用了以下 3 種 golang GC 優化方法。

    1)定制 golang HTTP 包:

    調整 HTTP 協議 conn 數據結構默認分配讀寫緩沖區的大小,以及手動維護讀寫緩存池,減少動態開辟內存的次數,降低 GC 壓力。

    在 Go 語言原生的 HTTP 包中會為每個請求默認分配 8KB 的緩沖區,讀、寫緩沖區各 4K。而在我們的服務場景中只有 GET 請求,服務需要的信息都包含在 HTTP header 中,并沒有 body,實際上不需要如此大的內存進行存儲,所以我們調小了讀寫緩沖區,將讀緩沖區調小到 1K,寫緩沖區調小到 32B,golang 的 bufio 在寫緩沖區較小時,會直接寫出。

    從 golang 1.3 開始,HTTP 原生的包中已經使用了sync.Pool 維護讀寫緩存池,但是 sync.Pool 中的數據會被自動的回收,同樣會小量的增加 GC 壓力,我們此處自己維護緩存池來減少垃圾回收。

    2)加快資源釋放:

    原生的 HTTP 包默認使用 keep-alive 的方式,小米搶購場景下,惡意流量占用了大量的連接,我們通過主動設置 response header 的 connection 為 close 來主動關閉惡意連接,加快 goroutine 資源的釋放。

    3)升級版本:

    跟進使用 golang 最新的版本,golang 后續的每個版本都有針對 GC 能力的調整。

    得益于開源技術力量,以及大秒系統在 GC 優化上的努力,以及系統層的調優,我們的 HTTP 限流層已經可以余量前行。

    從上圖可以看出,得益于 GC 的優化,2015 年米粉節,每輪搶購,HTTP 服務的內存不會有特別大的抖動。

    10.2 HTTP 服務器內存調優之操作系統參數調整

    我們的服務場景下絕大多數的請求數都是惡意請求,惡意請求通常都是短連接請求,大量的短連接會處于 timewait 狀態,幾分鐘之后才會釋放,這樣會占用大量的資源,通過調整內核參數,盡快釋放或者重用 timewait 狀態的連接,減少資源的開銷。

    具體參數調整如下:

    net.ipv4.tcp_tw_recycle = 1 (打開TIME-WAIT sockets快速回收)

    net.ipv4.tcp_tw_reuse = 1 (允許TIME-WAIT sockets復用)

    net.ipv4.tcp_max_tw_buckets=10000  (降低系統連接數和資源占用,默認為18w)

    高并發場景下,操作系統層網絡模塊參數的調整,會起到事半功倍的效果。

    10.3 沒有通信就談不上分布式系統

    整個大秒系統模塊之間面臨的通信要求是非常苛刻的,Master 節點與 HTTP、Middle 節點要頻繁的廣播控制命令,dcacenter要實時的收集 HTTP、Middle 節點的監控管理數據,HTTP 要將用戶的購買請求路由到 Middle 節點之間,Middle 節點要返回給相應的 HTTP 節點放號信息;

    我們基于 TCP 定制了簡單、高效的通信協議,對于 HTTP 層和 Middle 層通信,通信模塊能夠合并用戶請求,減少通信開銷,保障整個大秒系統的高效通信,增加服務的處理能力。

    10.4 服務閉環設計

    從上述搶購的服務閉環架構中可以看出,整個搶購流程處理bigtap系統之外,還有 cart 服務,中心 counter 服務,這三者與 bigtap 系統構成了一個數據流的閉環,但是在大秒最初的設計中,是沒有 counter 服務的,Middle層策略集群在放號的同時,又作為計數服務存在,但是整個搶購流程卻是以商品加入購物車代表最終的搶購成功,這在設計上有一個漏洞,假如 bigtap 計數了,但是token 并沒有請求加購物車成功,這是不合理的。為了保證整個系統的準確性,我們增加了計數器服務,計數操作發生在加購物車下游,bigtap 在從計數中心取出商品實時銷量,由此,構成一個服務閉環設計。在提升了系統的準確性,同時也保證了用戶體驗。

    10.5 技術的選擇要可控

    我們一開始選擇使用 ZooKeeper 存放商品的配置信息,在搶購活動的過程伴隨著大量的配置變更操作,ZooKeeper 的 watch 機制不適合用于頻繁寫的場景,造成消息丟失,大秒前端集群狀態與配置不一致。

    后來,我們將所有的配置信息存放在 Redis 中,基于通信模塊,在發生配置變更時,伴隨著一次配置項變更的廣播通知,大秒前端根據相應的通知命令,拉取 Redis 中相應的配置信息,變更內存中配置及狀態。

    11、“大秒”的幾點設計原則

    在設計“大秒”的過程中,我們總結了下面這些原則:

    1)分治是解決復雜問題的通則:我們從第一代搶購系統演進到當前的大秒系統,衍生出了很多服務,每個服務的產生都是為了專門解決一個問題,分離整個復雜系統,針對每個服務需要解決的問題,各個擊破,重點優化。由此,才保障了秒殺體系整體性能、可靠性的提升;

    2)服務化設計:系統解耦,增強系統的伸縮性與可靠性;

    3)無狀態設計:增強系統的伸縮性,提升集群整體處理能力;

    4)狀態數據局部化:相對于數據中心化,提升集群整體處理能力;

    5)中心化監控管理、熱備部署:既保證了服務的高可用性,又能夠提升開發和管理效率。隨著集群規模的增大以及管理數據的增多,分離管理信息到不同的數據管理節點,實現管理能力的擴容。通常情況下,中小型分布式系統,單機管理能力即可滿足;

    6)避免過度設計、過早的優化:小步快跑,頻繁迭代;

    7)沒有華麗的技術,把細小的點做好:不回避問題,特別是在高并發系統中,一個細小的問題,都可以引發整個服務雪崩。

    12、Q&A

    1)實時倉庫怎么避免超賣?

    我們的搶購系統以加入購物車代表購買成功,因為用戶要買配件等,庫存是由計數器控制的,先限流,在計數,在可控的并發量情況下,不會出現超賣。

    2)有了放號系統計算放號規則,為什么還需要一個外圍的 counter?

    主要是 bigtap 到 cart 的環節 token 有丟失,在 cart 之后再加一個計數器,保障銷量,bigtap 再讀取計數器的數據控制前端商品銷售狀態,整個延遲不超 3s。

    3)HTTP 集群通過 uuid hash 到 Middle,如果目標 Middle 已經死掉怎么應對?

    這個問題在文章中有強調,在我們的場景下,商品迅速賣完,這塊沒有做高可用,只是從代碼層面做 review,完善異常處理機制,并且通常情況下,middle 負載不是特別高,幾百次活動下來,還沒出現過掛掉情況。

    4)防刷系統是離線計算的嗎,還是有在線識別的策略?

    基于日志,準實時,因為請求量比較大,專門搭了一套 Kafka 服務轉儲日志,基于 golang 開發 logcollect 與 antiblack 模塊,可以達到很高的處理性能。

    5)請問如何模擬大量請求做測試?

    我們遇到的情況是,由于壓測機單機端口限制造成早期不好測試,我們這邊壓測團隊基于開源模塊開發了能夠模擬虛擬IP的模塊,打破了單機端口的限制。

    6)即使廣播和 Redis 拉取商品配置信息,仍有可能配置信息不一致如何解決?

    這個主要是商品的配置和狀態信息,不涉及到強一致性要求的場景,我們這樣可以在秒級達到最終一致性。

    附錄:更多架構設計方面的文章

    [1] 有關IM架構設計的文章:

    淺談IM系統的架構設計

    簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端

    一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文)

    一套原創分布式即時通訊(IM)系統理論架構方案

    從零到卓越:京東客服即時通訊系統的技術架構演進歷程

    蘑菇街即時通訊/IM服務器開發之架構選擇

    騰訊QQ1.4億在線用戶的技術挑戰和架構演進之路PPT

    微信后臺基于時間序的海量數據冷熱分級架構設計實踐

    微信技術總監談架構:微信之道——大道至簡(演講全文)

    如何解讀《微信技術總監談架構:微信之道——大道至簡》

    快速裂變:見證微信強大后臺架構從0到1的演進歷程(一)

    17年的實踐:騰訊海量產品的技術方法論

    移動端IM中大規模群消息的推送如何保證效率、實時性?

    現代IM系統中聊天消息的同步和存儲方案探討

    IM開發基礎知識補課(二):如何設計大量圖片文件的服務端存儲架構?

    IM開發基礎知識補課(三):快速理解服務端數據庫讀寫分離原理及實踐建議

    IM開發基礎知識補課(四):正確理解HTTP短連接中的Cookie、Session和Token

    WhatsApp技術實踐分享:32人工程團隊創造的技術神話

    微信朋友圈千億訪問量背后的技術挑戰和實踐總結

    王者榮耀2億用戶量的背后:產品定位、技術架構、網絡方案等

    IM系統的MQ消息中間件選型:Kafka還是RabbitMQ?

    騰訊資深架構師干貨總結:一文讀懂大型分布式系統設計的方方面面

    以微博類應用場景為例,總結海量社交系統的架構設計步驟

    快速理解高性能HTTP服務端的負載均衡技術原理

    子彈短信光鮮的背后:網易云信首席架構師分享億級IM平臺的技術實踐

    知乎技術分享:從單機到2000萬QPS并發的Redis高性能緩存實踐之路

    IM開發基礎知識補課(五):通俗易懂,正確理解并用好MQ消息隊列

    微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)

    微信技術分享:微信的海量IM聊天消息序列號生成實踐(容災方案篇)

    新手入門:零基礎理解大型分布式架構的演進歷史、技術原理、最佳實踐

    一套高可用、易伸縮、高并發的IM群聊架構方案設計實踐

    阿里技術分享:深度揭秘阿里數據庫技術方案的10年變遷史

    阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路

    >> 更多同類文章 ……

    [2] 更多其它架構設計相關文章:

    騰訊資深架構師干貨總結:一文讀懂大型分布式系統設計的方方面面

    快速理解高性能HTTP服務端的負載均衡技術原理

    子彈短信光鮮的背后:網易云信首席架構師分享億級IM平臺的技術實踐

    知乎技術分享:從單機到2000萬QPS并發的Redis高性能緩存實踐之路

    新手入門:零基礎理解大型分布式架構的演進歷史、技術原理、最佳實踐

    阿里技術分享:深度揭秘阿里數據庫技術方案的10年變遷史

    阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路

    達達O2O后臺架構演進實踐:從0到4000高并發請求背后的努力

    優秀后端架構師必會知識:史上最全MySQL大表優化方案總結

    小米技術分享:解密小米搶購系統千萬高并發架構的演進和實踐

    >> 更多同類文章 ……

    (本文同步發布于:http://www.52im.net/thread-2323-1-1.html



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 亚洲精品免费网站| 亚洲丰满熟女一区二区v| 免费看大美女大黄大色| 午夜老司机永久免费看片| 亚洲午夜精品一级在线播放放| 成人免费福利视频| 久久国产免费观看精品| 一区二区三区在线免费观看视频| 色www永久免费| 亚洲国产成人精品无码区花野真一| 亚洲精品亚洲人成在线麻豆| 国产精品亚洲一区二区三区在线 | 成年性羞羞视频免费观看无限| 99热这里只有精品6免费| 岛国岛国免费V片在线观看| 美美女高清毛片视频黄的一免费| 亚洲人成未满十八禁网站| 亚洲国产精品久久丫| 亚洲综合视频在线观看| 亚洲欧洲国产日韩精品| 久久久久久久综合日本亚洲| 国产国拍精品亚洲AV片| 亚洲熟妇少妇任你躁在线观看无码| 亚洲AV无码乱码在线观看性色扶 | 亚洲电影在线免费观看| 久久精品国产亚洲AV高清热| 久久精品国产96精品亚洲| 亚洲国产精品无码专区影院| 亚洲成A人片在线观看无码不卡| 国产亚洲av人片在线观看| 国产成人综合亚洲AV第一页 | 中文字幕乱码系列免费| 亚洲一区二区三区免费| 美女被羞羞网站免费下载| 国产成人精品亚洲一区| 免费一区二区三区在线视频| eeuss影院ss奇兵免费com| 中文字幕在线免费视频| 免费国产午夜高清在线视频| 四虎成人精品永久免费AV| 中文字幕无码播放免费|