本文原文內容引用自高可用架構公衆號,內容有整理和修訂。php
你們對下面這個排隊的場景應該很是熟悉,這個是小米手機搶購的用戶排隊交互圖,你們看到這些排隊的兔子時,說明也有不少用戶在同一時間向小米搶購系統提交了購買請求。html
▲ 小米手機搶購排隊中...前端
小米搶購系統後端服務面臨巨大的壓力,下圖能夠反映小米搶購系統面臨的瞬間峯值壓力。這張圖截取自某年米粉節大秒服務後端其中一組LB(負載均衡層)的每分鐘請求總數的狀況(橫軸的時間是UTC時間),如你們能夠想象到的同樣,峯值流量是普通狀況下流量的近10倍。node
▲ 某年米粉節大秒服務後端其中一組負載均衡層的QPS統計狀況python
以上就是小米搶購活動時後端服務集羣面臨的壓力。小米搶購系統從2011年末誕生到成長爲一個扛過2次米粉節和屢次爆品首發的高性能、高可靠的峯值系統,經歷了不少次大大小小的架構演進,本次分享將爲你們解密該系統的技術演進、設計思路、實踐總結等,但願能帶給您啓發。nginx
(本文同步發佈於:http://www.52im.net/thread-2323-1-1.html)golang
馬利超:小米科技的系統研發與大數據工程師,2013年畢業於大連理工大學,畢業後有幸加入小米搶購系統團隊,並參與了小米搶購系統開發、重構與調優。其人熱愛技術,對分佈式系統架構、高併發峯值系統、大數據領域、反做弊領域、搜索/廣告/推薦系統有濃厚的興趣。redis
《新手入門:零基礎理解大型分佈式架構的演進歷史、技術原理、最佳實踐》算法
《達達O2O後臺架構演進實踐:從0到4000高併發請求背後的努力》數據庫
《騰訊資深架構師乾貨總結:一文讀懂大型分佈式系統設計的方方面面》
2011底,在小米手機首批30萬所有發完貨以後,接下來即是你們熟知的,每週二中午十二點,小米手機開放購買。在開放購買期間,海量的用戶請求瞬間衝擊過來,對於當時小米這樣一個初創公司,特別是一個剛成立不到半年的電商團隊來講,面臨的挑戰是巨大的。
面臨的問題大體以下:
1)第一次開放購買,在小米商城主站進行,在瞬時壓力下,整個主交易系統並無逃脫掛掉的命運;
2)開放購買活動是結束了,可是一週以後,下一輪的開放購買已經開始開放預定,開放購買又會如期而至。
爲了保證下次開放購買順利進行,留給小米網工程師團隊的時間是有限的,只有短短的7天時間。
通過技術團隊討論,爲了不搶購時的峯值流量壓垮整個小米網,決定設計一套獨立的搶購系統。預定用戶經過在這套獨立的搶購系統中搶到購買資格,購買資格會異步的由資格數據同步模塊同步到用戶的購物車中,從用戶搶到手機那一時刻起,在規定的時間內,用戶小米商城完成下單和支付。
今後這版獨立的搶購系統承接了小米的全部的搶購,經歷過大大小小的優化與重構,最後又演化爲整個小米網的限流峯值系統。這版最初的搶購系統內部代號:TD。
這套系統早期的架設設計出發點是:
1)併發能力要儘可能的高,能承受瞬時的峯值;
2)不能超賣(可容忍小量的超賣);
3)只有預定用戶能夠購買,一個用戶只能買一臺;
4)要很是可靠,購買記錄不可丟失。
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是否可以及時的處理這些資格記錄?
基於上述問題,接下來咱們來看小米新一代搶購系統,也能夠理解爲增強版。
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的小米搶購系統(內部稱爲「大秒」),也是本文的分享重點,請繼續往下閱讀。
接上節,咱們繼續詳細介紹這套最新架構。
時間回到2014年初,當時公司決定舉辦一場「米粉節」活動,全天6輪活動,多個國家、多款爆品同時參與搶購。業務場景將變得更加複雜,當天的併發壓力也會有一個量級的提高,原有的搶購系統已經不能適應如此複雜的業務場景了。
爲此,小米網技術團隊基於對 golang 應對高併發、大規模分佈式系統能力的確定,徹底基於 golang,從新設計了搶購系統,也就是咱們目前使用的搶購限流峯值系統——「大秒」。
在整個系統設計的之初,咱們充分考慮了:
1)靈活性及可運營性;
2)可運維性及可伸縮性;
3)限流與搶購放號的精準性。
從大秒第一天誕生到演化至今有不少次重構與優化,但一直沿用了設計之初的結構,接下來咱們詳細瞭解下這套架構的技術設計以及填過的一些坑。
大秒系統主要由以下幾個模塊構成:
1)限流集羣 HTTP 服務;
2)放號策略集羣 Middle 服務;
3)監控數據中心 Dcacenter;
4)監控管理體系 Master;
5)準實時防刷模塊 antiblack;
6)基礎存儲與日誌隊列服務:Redis 集羣、Kafka 集羣等。
整個大秒體系中大秒前端模塊 (HTTP/middle/antiblack) 和監控數據中心使用 golang 開發,大秒監控管理體系使用 Python + golang 開發。
「大秒」前端的架構設計從三個系統展開:
1)限流集羣 HTTP 服務;
2)策略集羣 Middle 服務;
3)準實時反做弊 antiblack 服務。
搶購高峯時,一般會有幾百萬的用戶同時請求,瞬時流量很是大,HTTP 集羣頂在最前線,接受用戶的請求,將合法的請求發送的處理隊列,處理隊列設置必定的長度限制,一般狀況下,搶購用戶數與銷售商品的比例在100:1,甚至更高,爲了不繫統不被沖垮,保障絕大多數用戶的體驗,咱們認爲流量是部分可丟失的,當處理隊列滿時,丟棄入隊請求;
雖然設計上過載流量是部分可丟棄的,可是策略層處理能力是很是 power 的,即使是須要丟棄流量,也是按流量的惡意程度,逐級丟棄的,正經常使用戶購買請求不受影響。
咱們使用基於規則的識別、離線畫像信息、機器學習邏輯迴歸等方法,識別惡意用戶,在系統高負載的狀況下,這部分請求能夠優先阻擊其發送到策略層,優先處理正經常使用戶的請求,保障用戶體驗過。
HTTP集羣中不一樣節點之間的所持用的狀態數據是一致的,處理邏輯也是一致的,因此整個集羣中的任何一個節點掛掉,在前端負載均衡能力下,服務的準確性與一致性不受任何影響。
HTTP 模塊將知足條件用戶的請求按照 uid 哈希的規則,轉發到 Middle 集羣中相應的節點,Middle 集羣根據商品放號策略判斷 (uid:sku:time) 組合是否能夠分配購買資格,並返回給相應的 HTTP 服務;
使用 Middle 服務本地內存維護用戶的購買記錄信息,支持各類購買規則,好比:單次活動不限購買數量,單次活動僅限購買一款商品,單次活動每款商品僅限購買一次。
咱們將 Middle 的放號邏輯抽象成一個有限狀態機,由商品的放號策略配置閾值來觸發放號狀態轉換,整個配置由 Master 節點統一管理與調度。
爲了提高整個系統的處理能力,咱們將用戶狀態數據局部化,單用戶(uid)的全部相關信息所有路由到一臺 Middle 節點上處理。
可是有一點風險是,Middle 集羣中服務可能會出現活動過程當中掛掉的風險,在搶購場景下,商品基本上是瞬時賣完,爲了保障系統的處理能力,咱們主要從代碼層面作優化,review 代碼邏輯,保證服務應對異常的處理能力。
雖然理論上存在風險,可是在實際工程中,經歷過幾百次活動,還沒出現 Middle 節點掛掉的狀況。
基於日誌流的防刷架構,在每臺 HTTP 節點上部署日誌收集 Agent,使用高吞吐量的 Kafka 作日誌轉儲隊列,antiblack 模塊實時分析用戶請求日誌,基於 IP 粒度、Uid 粒度等作防刷。
雖然此處將 antiblack 模塊定義爲準實時防刷模塊,可是做弊信息識別的延遲時長在 1 分鐘以內,其中主要的時延發生在日誌的轉儲過程當中。
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直接做爲數據中心,主要是出於數據的實時性考慮,省去中間轉儲環節,上層可視化系統、自動化活動控制系統、規則引擎系統等能夠第一時間得到前端實時的銷售狀態數據及服務的狀態數據。
監控管理中心的主要模塊以下。
a.倉儲庫存同步服務StockKeeper:
同步商品的倉儲系統中的實時庫存到秒殺系統,大秒系統擁有雙庫存保障,一個是實時倉儲庫存,一個是虛擬庫存也就是資格號,在搶購場景下只有當兩個庫存都有貨時,才能正常銷售。
b.商品策略控制器PolicyKeeper:
基於相應的策略觸發器(時間區間與庫存區間),當策略觸發時,好比12點整,搶購開始,爲相應的商品配置策略,並向大秒前端廣播商品配置變動命令,在通訊基礎模塊的保障下,整個過程秒級內完成。
c.活動自動化控制ActKeeper:
基於監控數據中心獲取大秒前端的實時銷售數據,自動化的控制活動中的各個狀態,活動開始前逐層打開開關,活動開始時打開最後開關,活動過程當中維護活動的售罄狀態,活動結束後初始化,整個搶購活動的過程無需人工介入;
d.數據可視化:
從監控數據中心提取實時的結構化系統級監控數據和業務級監控數據,將活動過程當中的詳細數據實時可視化到管理頁面上,讓運營與銷售以及大秒管理員可以及時瞭解當前活動狀態,並人工干預活動;
e.監控規則引擎:
監控規則引擎創建在監控數據中心之上,根據結構化監控數據判斷當前整個搶購系統的狀態,及時報警,以及半自動化控制。
f.其餘:
大秒管理端管理大秒前端全部的數據、配置以及狀態,Master體系提供了詳細的管理工具與自動化服務。若是清理大秒前端Middle服務中的用戶購買信息等。
整個搶購系統由 Master 體系中各個服務作統一的控制的,Master 控制商品狀態及配置數據的變動,控制當前活動的狀態,控制商品放號的策略等。
爲了保證時效性,商品、活動、系統等配置狀態的變動都須要將變動命令廣播前端集羣,這期間發生了大量的分佈式系統間通訊,爲了保障命令及時下行,咱們提取出了命令轉發服務:MdwRouter,用於廣播控制命令到大秒前端集羣。該服務模塊維護了到大秒前端長鏈接,接收 Master 下發的控制命令,並瞬時廣播,保障了整個控制流的處理能力。
舉個例子:
某年米粉節,咱們單機房大秒集羣的規模在過百臺級別,假設爲 100 臺,管理的獨立的商品id的數量在 400 個左右,在這種量級的活動下,商品的放行策略是批量管理的,好比咱們根據後端交易系統的壓力反饋,調整全部商品的放行速度,這時候須要廣播的命令條數在: 100*400=40000 級別,Mdwrouter 很好的保障了系統命令下行的速度,秒級完成命令下行。
▲ 整個小米網搶購系統服務閉環
整個小米網搶購系統服務閉環如上圖所示:
1)bigtap體系中大秒前端服務負責搶購時限流放號,並控制放號策略以及維護用戶在本地緩存中的購買記錄;
2)cart服務驗證token的有效性,並向counter服務發起銷量驗證請求;
3)counter服務是整個搶購系統最終的計數器, 海量的請求在bigtap服務的做用下已經被限制在能夠承受的壓力範圍內,而且複雜的放號策略已經在大秒Middle服務中實現,counter只負責最終的計數便可。counter服務採用redis記錄相應商品的放號狀況,根據預設的銷量,判斷當前請求加購物車商品是否有庫存餘量,並維護商品銷量;
4)bigtap體系中的dcacenter服務實時採集商品銷量,Master中活動自動化控制服務依據商品銷量判斷當前商品是否售罄,售罄則經過設置商品的售罄狀態,並通知大秒前端。
從上述整個服務閉環設計能夠看出,「大秒」的功能徹底能夠抽象成限流系統,只有在處理搶購活動時,數據的管理與一致性要求才使整個系統變得複雜。
2015年米粉節,咱們徹底使用大秒的限流功能,不限用戶的購買數量,很便捷的將系統部署在兩個機房,一個物理機房,一個公有云集羣,二者同時服務,大秒系統做爲整個商城的最前端,可以根據後端服務的壓力狀態,瞬時調整整個集羣放行流量大小,很是好的保障了整個米粉節的正常舉行。
正如您看到在上述文章中介紹的那樣,這些服務設計的每一次優化的背後,都至少有一次慘痛的經歷,針對這些經歷,咱們也作了大量的總結,這些總結將在下兩節的內容裏進行總結性地分享。
咱們從 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 服務的內存不會有特別大的抖動。
咱們的服務場景下絕大多數的請求數都是惡意請求,惡意請求一般都是短鏈接請求,大量的短鏈接會處於 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)
高併發場景下,操做系統層網絡模塊參數的調整,會起到事半功倍的效果。
整個大秒系統模塊之間面臨的通訊要求是很是苛刻的,Master 節點與 HTTP、Middle 節點要頻繁的廣播控制命令,dcacenter要實時的收集 HTTP、Middle 節點的監控管理數據,HTTP 要將用戶的購買請求路由到 Middle 節點之間,Middle 節點要返回給相應的 HTTP 節點放號信息;
咱們基於 TCP 定製了簡單、高效的通訊協議,對於 HTTP 層和 Middle 層通訊,通訊模塊可以合併用戶請求,減小通訊開銷,保障整個大秒系統的高效通訊,增長服務的處理能力。
從上述搶購的服務閉環架構中能夠看出,整個搶購流程處理bigtap系統以外,還有 cart 服務,中心 counter 服務,這三者與 bigtap 系統構成了一個數據流的閉環,可是在大秒最初的設計中,是沒有 counter 服務的,Middle層策略集羣在放號的同時,又做爲計數服務存在,可是整個搶購流程倒是以商品加入購物車表明最終的搶購成功,這在設計上有一個漏洞,假如 bigtap 計數了,可是token 並無請求加購物車成功,這是不合理的。爲了保證整個系統的準確性,咱們增長了計數器服務,計數操做發生在加購物車下游,bigtap 在從計數中心取出商品實時銷量,由此,構成一個服務閉環設計。在提高了系統的準確性,同時也保證了用戶體驗。
咱們一開始選擇使用 ZooKeeper 存放商品的配置信息,在搶購活動的過程伴隨着大量的配置變動操做,ZooKeeper 的 watch 機制不適合用於頻繁寫的場景,形成消息丟失,大秒前端集羣狀態與配置不一致。
後來,咱們將全部的配置信息存放在 Redis 中,基於通訊模塊,在發生配置變動時,伴隨着一次配置項變動的廣播通知,大秒前端根據相應的通知命令,拉取 Redis 中相應的配置信息,變動內存中配置及狀態。
在設計「大秒」的過程當中,咱們總結了下面這些原則:
1)分治是解決複雜問題的通則:咱們從第一代搶購系統演進到當前的大秒系統,衍生出了不少服務,每一個服務的產生都是爲了專門解決一個問題,分離整個複雜系統,針對每一個服務須要解決的問題,各個擊破,重點優化。由此,才保障了秒殺體系總體性能、可靠性的提高;
2)服務化設計:系統解耦,加強系統的伸縮性與可靠性;
3)無狀態設計:加強系統的伸縮性,提高集羣總體處理能力;
4)狀態數據局部化:相對於數據中心化,提高集羣總體處理能力;
5)中心化監控管理、熱備部署:既保證了服務的高可用性,又可以提高開發和管理效率。隨着集羣規模的增大以及管理數據的增多,分離管理信息到不一樣的數據管理節點,實現管理能力的擴容。一般狀況下,中小型分佈式系統,單機管理能力便可知足;
6)避免過分設計、過早的優化:小步快跑,頻繁迭代;
7)沒有華麗的技術,把細小的點作好:不迴避問題,特別是在高併發系統中,一個細小的問題,均可以引起整個服務雪崩。
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開發基礎知識補課(四):正確理解HTTP短鏈接中的Cookie、Session和Token》
《WhatsApp技術實踐分享:32人工程團隊創造的技術神話》
《王者榮耀2億用戶量的背後:產品定位、技術架構、網絡方案等》
《IM系統的MQ消息中間件選型:Kafka仍是RabbitMQ?》
《騰訊資深架構師乾貨總結:一文讀懂大型分佈式系統設計的方方面面》
《子彈短信光鮮的背後:網易雲信首席架構師分享億級IM平臺的技術實踐》
《知乎技術分享:從單機到2000萬QPS併發的Redis高性能緩存實踐之路》
《IM開發基礎知識補課(五):通俗易懂,正確理解並用好MQ消息隊列》
《微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)》
《微信技術分享:微信的海量IM聊天消息序列號生成實踐(容災方案篇)》
《新手入門:零基礎理解大型分佈式架構的演進歷史、技術原理、最佳實踐》
《阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路》
>> 更多同類文章 ……
[2] 更多其它架構設計相關文章:
《騰訊資深架構師乾貨總結:一文讀懂大型分佈式系統設計的方方面面》
《子彈短信光鮮的背後:網易雲信首席架構師分享億級IM平臺的技術實踐》
《知乎技術分享:從單機到2000萬QPS併發的Redis高性能緩存實踐之路》
《新手入門:零基礎理解大型分佈式架構的演進歷史、技術原理、最佳實踐》
《阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路》
《達達O2O後臺架構演進實踐:從0到4000高併發請求背後的努力》
《優秀後端架構師必會知識:史上最全MySQL大表優化方案總結》
《小米技術分享:解密小米搶購系統千萬高併發架構的演進和實踐》
>> 更多同類文章 ……
(本文同步發佈於:http://www.52im.net/thread-2323-1-1.html)