从技术角度谈一谈,我参与设计开发的手Q春节红包项目--转
原文地址:http://chuansong.me/n/1608115051125
作者|吳逸翔編輯|唐聰
今年春節(jié)期間,QQ以AR技術(shù)為支撐、娛樂體驗為導(dǎo)向在春節(jié)期間推出系列紅包并成功刷屏,系列紅包包括三大玩法+年初一彩蛋,分別是“LBS+AR天降紅包”、刷一刷紅包和“面對面”紅包,加上“娛樂紅包”(明星刷臉紅包),共計在春節(jié)期間派發(fā)了2.5億現(xiàn)金紅包和價值30億的卡券禮包。根據(jù)企鵝智酷提供的數(shù)據(jù),手機QQ的用戶滲透率在全平臺排名第二,為52.9%(第一是微信)。本文將會詳細(xì)介紹手Q春節(jié)紅包項目的設(shè)計、容災(zāi)、運維、架構(gòu)以及總結(jié)。
先來介紹下整個過程中,手Q紅包的玩法,以方便不了解的同學(xué)理解。2017年的手Q春節(jié)游戲紅包共有刷一刷/AR地圖/掃福三種,如下圖所示:
雖然紅包分三種,但在游戲業(yè)務(wù)側(cè)這邊的體驗都是一樣:用戶得到一個紅包卡券,打開后展示一個(刷一刷紅包)或者多個(AR地圖紅包)游戲的禮包列表,用戶選擇一個禮包后彈出區(qū)服組件,用戶確認(rèn)對應(yīng)的區(qū)服角色信息后會禮包會在48個小時內(nèi)發(fā)放到賬。體驗如下:
游戲紅包的設(shè)計容量為入口卡券頁流量80k/s,以上體驗流程一共涉及三個后臺接口:
-
禮包列表:用戶界面的禮包內(nèi)容需要根據(jù)后臺接口返回禮包列表進行排序和過濾展示。
-
區(qū)服選擇:用戶界面彈出的區(qū)服組件需要后臺接口返回用戶區(qū)服角色信息。
-
領(lǐng)取禮包:用戶點擊“確認(rèn)”按鈕領(lǐng)取禮包,后臺進行游戲道具發(fā)貨。
需求分析?禮包列表
這個功能使用現(xiàn)有能力比較容易解決。活動共有十種游戲,每個游戲有兩種禮包:拉新(面向非注冊用戶,價值80元)/拉活躍(面向注冊用戶,價值20元),一個用戶只能獲得這兩種禮包中的一種,產(chǎn)品策略允許拉新的用戶獲得價值較低的拉活躍禮包,反之則不允許。頁面展示按用戶偏好排序十個游戲,每個游戲展示一個拉新禮包或者一個拉活躍禮包。
出于降低除夕當(dāng)前流量負(fù)載和柔性考慮,在紅包活動前,十種游戲的禮包內(nèi)容作為前端靜態(tài)數(shù)據(jù)已經(jīng)預(yù)先通過離線包/CDN下發(fā);紅包活動時,后臺接口根據(jù)用戶偏好返回的游戲禮包列表,只是提供前端禮包內(nèi)容進行過濾和排序,失敗了也有前端默認(rèn)的游戲禮包列表,保障用戶體驗。
過濾:讀取存儲,用戶有注冊的游戲返回活躍禮包,用戶沒有注冊的游戲返回拉新禮包
排序:一個兩層排序,第一層排序讀取存儲(key為用戶,value為用戶所注冊的游戲列表),用戶注冊的游戲(拉活躍)排在用戶沒有注冊的游戲(拉新)前面;第二層排序,對于拉新游戲列表和拉活躍游戲列表內(nèi)部,使用神盾算法對用戶這10款游戲的偏好再進行二次排序。對于外部接口的依賴只有CMEM存儲和神盾算法接口,這兩個接口以及合并這兩種數(shù)據(jù)給出最終的個性化推薦禮包列表接口都可以平行擴容以支持100k級別的QPS。
?區(qū)服信息
這個功能是現(xiàn)有能力。這個角色信息的來源是IDIP,但由于該接口較緩慢(2s左右)且容量較低(低于10k/s),故后臺做了一層緩存,將IDIP的區(qū)服信息永久性緩存到CMEM中,前臺也有本地緩存,在實踐中,前臺緩存命中率為60%,后臺為35%,多級緩存后走到IDIP的請求量只有5%,對IDIP影響不大,只需要擴容現(xiàn)有的區(qū)服server和CMEM即可。
?領(lǐng)取禮包
這個功能使用現(xiàn)有能力解決存在困難。游戲中心日常發(fā)貨的道具和平臺比較多,平臺分為IEG-AMS/MP兩種,MP發(fā)貨對于發(fā)游戲道具和發(fā)Q幣又是兩種接口,故我們在架構(gòu)上使用Facade模式,使用AMS作為發(fā)貨proxy,屏蔽了底層發(fā)貨的復(fù)雜性,向游戲中心提供統(tǒng)一的發(fā)貨接口,但比較遺憾的是從AMS到游戲的發(fā)貨接口都是同步接口,發(fā)貨能力較低,發(fā)貨能力最高的王者榮耀也只承諾了3k/s的發(fā)貨速度,明顯不足以直接承受100k/s級別的紅包發(fā)貨,故這里的核心問題是需要有一個隊列來解決生產(chǎn)/消費速度不對等的問題。
去年的紅包是后臺收到發(fā)貨請求后落地到本地文件返回用戶成功,再由一個本機的daemon跑落地文件按游戲方所能提供的發(fā)貨速度進行實際發(fā)貨,相當(dāng)于使用本地隊列緩沖。但這個方案存在某臺機器掛掉后如果不能恢復(fù)會丟失一部分本地的發(fā)貨數(shù)據(jù)造成漏發(fā),以及每個高并發(fā)業(yè)務(wù)都要重新做這一套東西不方便通用的問題。
從架構(gòu)上思考,其實最合理的方案是作為發(fā)貨proxy的AMS提供異步發(fā)貨的能力,將用來解決生成/消費速度不匹配的MQ做在AMS內(nèi)部,為業(yè)務(wù)提供通用的異步發(fā)貨能力,業(yè)務(wù)側(cè)就不需要考慮發(fā)貨超過游戲方能力的問題,新業(yè)務(wù)有類似的場景也不需要重新開發(fā)。
游戲中心是業(yè)務(wù)側(cè),AMS是平臺側(cè)的能力,屬于另一個中心的業(yè)務(wù),于是一開始我們準(zhǔn)備推動AMS做異步發(fā)貨的能力,這樣業(yè)務(wù)就只要調(diào)用發(fā)貨接口就可以了,很是方便。但事情并沒有想象中順利,與AMS的開發(fā)和PM開會溝通了幾次,異步發(fā)貨的能力他們也有做技術(shù)規(guī)劃,但年前他們有其它需求要做,沒有時間支持。和leader討論了一下這個能力最好還是放在AMS做成通用以便以后有同樣場景的業(yè)務(wù)使用,前臺也有同學(xué)開發(fā)過AMS功能,可以由游戲中心業(yè)務(wù)側(cè)的前后臺同學(xué)合作完成AMS異步發(fā)貨功能的開發(fā),在春節(jié)紅包中應(yīng)用,再將這個功能交接給平臺側(cè)的同學(xué)維護,達到雙贏的效果。
整體方案與項目分解
整體方案圖如上圖所示,由于整個項目涉及多方開發(fā),而且模塊較多,整個模塊的開發(fā)周期較長,作為一期開發(fā)的話無法跟上基礎(chǔ)側(cè)卡券的驗收和安排的幾次演習(xí)/壓測,故按“大系統(tǒng)小做”的原則,根據(jù)模塊的重要和緊急程度分為幾期迭代完成,每一期有獨立的里程碑目標(biāo)并達到對應(yīng)的驗收/演習(xí)/壓測要求:
-
第一期(方案圖左側(cè)部分)為功能需求,在12月9號上線通過卡券方面功能驗收,先使用當(dāng)前的同步發(fā)貨接口,對性能無特別要求。
-
第二期(方案圖右側(cè)偏左部分)為性能需求,在12月20號上線參加第一次演習(xí),對發(fā)貨進行異步化改造,要求直接面向用戶的外網(wǎng)發(fā)貨接口能支持100k QPS的峰值流量。
-
第三期(方案圖右側(cè)偏右部分)為容錯需求,在12月27號上線參加第二次演習(xí),對發(fā)貨進行對賬補送改造,保證發(fā)貨的可靠性。
-
第四期為監(jiān)控需求,在1月6號上線參加第三次演習(xí),確認(rèn)各項關(guān)鍵數(shù)據(jù)的采集,并將采集到的數(shù)據(jù)展現(xiàn)到一個統(tǒng)一視圖上,以便除夕期間值班人員實時了解紅包系統(tǒng)的整體運行情況和出數(shù)據(jù)報表。
需求開發(fā)?功能需求開發(fā)
核心問題:不同場景的數(shù)據(jù)一致性
為用戶推薦禮包,用戶領(lǐng)取時需要經(jīng)過{4.1AMS外網(wǎng)發(fā)貨新OP}校驗領(lǐng)取資格,后臺的推薦數(shù)據(jù)必須能和AMS的資格校驗數(shù)據(jù)能夠?qū)ι?#xff0c;否則會出現(xiàn)后臺推薦的禮包用戶領(lǐng)取時卻通不過AMS的資格校驗導(dǎo)致領(lǐng)取不了的問題。
接口處理的是單個游戲的領(lǐng)取禮包的請求,資格校驗操作判斷一個用戶是否注冊了某個游戲。這個是AMS現(xiàn)有的通用功能,數(shù)據(jù)存儲在AMS的CMEM中,簡化描述就是一個key-value模型,key為uin+appid,value如果有注冊則為1,沒有則為0(實際為了節(jié)省存儲空間,使用bitmap桶實現(xiàn),具體參見號碼包系統(tǒng)使用文檔),導(dǎo)入的數(shù)據(jù)源是產(chǎn)品在除夕前一周提供10款游戲的全量注冊號碼包,每個游戲一個文件,文件內(nèi)容是注冊用戶的QQ號。
但{3.1后臺禮包推薦接口}接口返回的是多個游戲的禮包列表,需要獲取十個游戲的用戶注冊狀態(tài)。如果讀取AMS現(xiàn)有的接口/存儲,會有兩個問題:
-
AMS號碼包服務(wù)也要承受等同于推薦列表接口48k/s的流量,需要進行擴容
-
AMS號碼包服務(wù)調(diào)用CMEM雖然可以一次請求合并10個key進行批量讀取,但請求到了CMEM的Access機還是要讀取多個Cache塊,性能并不如單請求單key讀取。
解決方案:同質(zhì)異構(gòu)的數(shù)據(jù)冗余
后臺將號碼包數(shù)據(jù)進行重新組織存儲到后臺申請的另外一個CMEM中,key為uin,value為用戶已注冊的appid列表,已注冊的游戲推薦拉活躍禮包,沒注冊的游戲推薦拉新禮包,這樣只需要查詢一次CMEM就可以得到十個游戲每個游戲的禮包推薦類型是拉新還是拉活躍。
由于AMS和后臺使用的是同一份號碼包數(shù)據(jù),只是應(yīng)用場景不同,數(shù)據(jù)組織形式不同,兩份CMEM數(shù)據(jù)同質(zhì)異構(gòu),故后臺推薦的禮包可以通過AMS的資格校驗。
?性能需求開發(fā)
核心問題:用戶領(lǐng)取禮包流量遠超游戲發(fā)貨能力
紅包活動具有時間短(單場5~30分鐘)、大用戶量參與(1.5億+)參與的特性,請求并發(fā)高,游戲紅包入口流量設(shè)計為80k/s,流經(jīng)各個模塊有衰減也有增幅,最終用戶領(lǐng)取禮包請求預(yù)估為96k/s,而游戲方提供的十款游戲總發(fā)貨能力只有5k/s(單款游戲最大為王者榮耀3k/s),請求峰值接近處理能力的20倍,同步調(diào)用會導(dǎo)致游戲方發(fā)貨接口過載,造成大面積發(fā)貨失敗,這個問題如何處理?
解決方案:發(fā)貨異步化
使用一個緩沖隊列來解決生產(chǎn)消費能力不對等的問題。用戶領(lǐng)取請求到達AMS進行基礎(chǔ)的資格校驗后將請求放入MQ中,返回用戶成功并告知會在48小時內(nèi)到賬。再由后臺發(fā)貨Daemon從MQ中讀取請求,通過限速組件控制保證以不超過游戲方發(fā)貨能力的速率進行發(fā)貨操作。使用的MQ是部門近來建設(shè)的RocketMQ,具體參見會員消息隊列(RocketMQ)接入指南。
?容錯需求開發(fā)
核心問題:安全發(fā)貨
三場活動發(fā)放的禮包總數(shù)預(yù)計將近4億,如何保障這些禮包對于合法用戶能都發(fā)貨到賬,不少發(fā)也不多發(fā)?如何防范高價值道具被惡意用戶刷走?有沒有可能內(nèi)部開發(fā)人員自己調(diào)用接口給自己發(fā)禮包?
解決方案:對賬補送/訂單號/安全打擊/權(quán)限控制
1. 訂單號解決不多發(fā)的問題
用戶領(lǐng)取禮包的接口{4.1AMS外網(wǎng)發(fā)貨新OP}調(diào)用成功,會為這個請求附帶一個UUID生成的一個全局唯一的訂單號,再放進MQ中,{4.3AMS內(nèi)網(wǎng)發(fā)貨OP}從MQ中取出消息,調(diào)用游戲方發(fā)貨接口前都會先校驗這個訂單號是否用過,沒用過則將訂單號以key的形式寫入CMEM,再進行發(fā)貨操作。如果出現(xiàn)對同一個發(fā)貨消息進行重復(fù)發(fā)貨,則會發(fā)現(xiàn)訂單號已經(jīng)用過了不會進行實際的發(fā)貨操作,保證以訂單號為標(biāo)識的同一個發(fā)貨請求只會進行一次發(fā)貨操作。
2. 對賬補送解決不少發(fā)的問題
發(fā)貨失敗是不可避免的,諸如網(wǎng)絡(luò)波動/游戲方發(fā)貨接口故障之類的問題都可能導(dǎo)致調(diào)用發(fā)貨接口失敗。在同步領(lǐng)取環(huán)境下,用戶可以通過重試在一定程度上解決這個問題。但是對于異步發(fā)貨,用戶點擊領(lǐng)取后發(fā)貨請求由{4.1AMS外網(wǎng)發(fā)貨新OP}放入MQ中就算成功了,即使后臺調(diào)用游戲的實際發(fā)貨接口失敗了沒有實際到賬,用戶對此也無感知不能進行重試但是會投訴,后臺發(fā)貨系統(tǒng)必須通過自身的容錯保證即使游戲方的發(fā)貨接口不穩(wěn)定偶爾會失敗,用戶所領(lǐng)的禮包能最終到。這里我們使用了對賬補送方案。
對賬:用戶領(lǐng)取禮包調(diào)用的接口{4.1AMS外網(wǎng)發(fā)貨新OP}成功寫應(yīng)發(fā)流水,{4.3AMS內(nèi)網(wǎng)發(fā)貨OP}調(diào)用游戲方發(fā)貨接口的寫實發(fā)流水,由于部分消息會堆積在消息隊列中,這部分稱為隊列堆積流水。故實際要進行補發(fā)操作的流水由以下公式可得:
失敗補發(fā)流水= 應(yīng)發(fā)流水 - 實發(fā)流水 - 隊列堆積流水。
由于訂單號的存在,可以保證同一個發(fā)貨請求重復(fù)發(fā)送也不會多發(fā),對隊列中堆積的消息提前進行補發(fā)操作也不會導(dǎo)致多發(fā)。故當(dāng)隊列中堆積的流水較少的時候,采用應(yīng)發(fā)流水與實發(fā)流水的差集作為失敗補發(fā)流水是合理,只是每個對賬周期會對隊列中堆積的消息進行兩次發(fā)貨操作,對性能略有損耗。
后臺每個小時運行一次增量對賬功能,檢測MQ消息堆積量量低于某個閾值,則進行對賬操作,截取上次對賬到此時的應(yīng)發(fā)流水/實發(fā)流水,兩者相減得到補發(fā)流水。
補送:對對賬操作得到的補發(fā)流水調(diào)用游戲方發(fā)貨接口進行發(fā)貨補送操作。
3. 安全打擊解決高價值道具防刷的問題
對于領(lǐng)獎的請求,都要求都要求帶上登錄態(tài),對用戶進行身份驗證,同時對于高價值的道具開啟安全打擊,上報安全中心進行惡意用戶校驗,防止被惡意用戶刷走。
4. 權(quán)限控制解決內(nèi)部人員監(jiān)守自盜的問題
對于發(fā)貨的機器都要安裝鐵將軍,用戶需要使用RTX名和token才能登錄機器,審計用戶在機器上的操作行為;
發(fā)貨模塊對于調(diào)用方是需要嚴(yán)格授權(quán),調(diào)用方需要申請key,包含程序路徑、程序MD5、部署模塊等信息,保證發(fā)貨功能不被隨意調(diào)用。
?監(jiān)控需求開發(fā)
核心問題:紅包涉及多個系統(tǒng)的自有監(jiān)控,數(shù)據(jù)收集困難
在監(jiān)控方面有兩個主要訴求:
我們對外提供的服務(wù)是否正常?如果有問題,如何快速地發(fā)現(xiàn)問題、分析問題?
實時知道用戶在整個系統(tǒng)的行為漏斗模型,每一步的轉(zhuǎn)化率是多少?
游戲紅包涉及紅包基礎(chǔ)側(cè)/業(yè)務(wù)前臺/業(yè)務(wù)后臺/AMS/MQ平臺等多個合作方,各個系統(tǒng)有自己的監(jiān)控系統(tǒng),數(shù)據(jù)來源不一致,活動當(dāng)天一個系統(tǒng)一個系統(tǒng)地收集的話效率太低。
解決方案:匯總各個系統(tǒng)的關(guān)鍵數(shù)據(jù)到一個視圖
紅包作為一個涉及多個子系統(tǒng)的聚合系統(tǒng),我們需要一個匯總了各個子系統(tǒng)關(guān)鍵數(shù)據(jù)的整體視圖,才能夠較全面地監(jiān)控業(yè)務(wù)核心指標(biāo),對系統(tǒng)和業(yè)務(wù)有較全面把控,避免在監(jiān)控系統(tǒng)中跳轉(zhuǎn)檢索而耗費有限的時間,為迅速響應(yīng)解決問題提供保證。
接口封裝:雖然紅包涉及的多個子系統(tǒng),各自有各自的上報方式和監(jiān)控系統(tǒng),但是對于關(guān)鍵數(shù)據(jù)大都有提供HTTP形式的查詢接口,我們通過封裝,將接口的定義統(tǒng)一為key-value形式,以(監(jiān)控項id,開始時間,結(jié)束時間)為key,value為(開始時間,結(jié)束時間)段內(nèi)監(jiān)控id的值之和。
配置化:一場紅包活動的監(jiān)控,可以由一個時間段加若干個監(jiān)控項定義。比如刷一刷紅包,時間段為除夕當(dāng)天20:00~20:30,監(jiān)控項為若干頁面的點擊量,若干禮包的發(fā)放量,若干后臺接口的請求量,若干MQ的堆積量等等。
通過對接口的封裝和配置化,新增一場紅包活動,只需要增加一個時間段和若干個監(jiān)控項的配置文件,比如下圖的AR/刷一刷混場/刷一刷專場就是通過3個配置文件定義3場活動,新增一場活動也只需要增加一個配置文件,并可以在一個視圖上靈活切換,相當(dāng)方便。
從上圖中我們就可以實時看到實發(fā)和應(yīng)發(fā)是大致相等的,隊列沒有出現(xiàn)堆積,用戶在各級頁面的轉(zhuǎn)化率,可以很方便地判斷系統(tǒng)的健康狀態(tài)和分析定位問題。
系統(tǒng)保障
第四部分講述了業(yè)務(wù)需求的開發(fā),但是否功能開發(fā)完成后我們就這樣就可放到線上安心睡大覺了呢?
-
如果出現(xiàn)一部分機器乃至整個機房掛了,服務(wù)是否可用?
-
外部的服務(wù)突然故障了,比如MQ突然掛了,不能寫入消息了,服務(wù)是否可用?
-
說是紅包入口流量8W/s,萬一來了20W/s呢?系統(tǒng)會不會掛掉?服務(wù)是否可用?
以下從系統(tǒng)容災(zāi)/過載保護/柔性可用/立體監(jiān)控來講我們這方面做的一些工作,我們對于除夕當(dāng)天出現(xiàn)各種問題系統(tǒng)還能正常運行,用戶能正常體驗服務(wù)的信心從何而來?
系統(tǒng)容災(zāi)
容災(zāi)就是在整體服務(wù)一部分出現(xiàn)異常時,另一部分能頂上,不影響整體服務(wù)的使用,保障業(yè)務(wù)可用、數(shù)據(jù)安全。但容災(zāi)設(shè)計會使得系統(tǒng)復(fù)雜度增加,成本和代價也增加,需要額外的開銷和資源,應(yīng)該在合理的范圍內(nèi)考慮容災(zāi)。
容災(zāi)級別一般劃分為多機容災(zāi)、多機房容災(zāi),多地容災(zāi),紅包的后臺服務(wù)主要使用公用組件的均衡負(fù)載和系統(tǒng)容災(zāi)能力,服務(wù)無單點問題,采用同地多機房部署,按多機房容災(zāi)標(biāo)準(zhǔn)設(shè)計。
?接入層
典型的GSLB+TGW+QZHTTP接入,GSLB解析域名把請求帶到離用戶最近的IDC的TGW接入機,TGW再通過內(nèi)網(wǎng)專線,把請求轉(zhuǎn)發(fā)到實際提供WEB服務(wù)的QZHTTP服務(wù)器上。
-
GSLB:Global Server Load Balance的首字母縮寫,意為全局負(fù)載均衡,主要提供提供域名解析的就近接入和流量調(diào)度。實現(xiàn)在廣域網(wǎng)(包括互聯(lián)網(wǎng))上不同地域的服務(wù)器間的流量調(diào)配,保證使用最佳的離自己最近的客戶服務(wù)器服務(wù),從而確保訪問質(zhì)量;它對服務(wù)器和鏈路進行綜合判斷來決定由哪個地點的服務(wù)器來提供服務(wù),實現(xiàn)異地服務(wù)器群服務(wù)質(zhì)量的保證。紅包使用獨立的sh.vip.hongbao.qq.com域名。
-
TGW:Tencent Gateway,是一套實現(xiàn)多網(wǎng)統(tǒng)一接入,支持自動負(fù)載均衡的系統(tǒng),TGW把外網(wǎng)不同運營商的請求,通過內(nèi)網(wǎng)隧道轉(zhuǎn)發(fā)給server,server返回數(shù)據(jù)時,再把數(shù)據(jù)通過內(nèi)網(wǎng)隧道返回給TGW,再由TGW發(fā)送給不同的運營商。紅包TGW外網(wǎng)部署了上海電信聯(lián)通雙VIP+香港CAP VIP。
-
QZHTTP:Web服務(wù)器,負(fù)責(zé)將HTTP請求轉(zhuǎn)成邏輯層使用的WUP協(xié)議,采用同地多機房部署部署。QZHTTP作為TGW的RS,TGW會周期性的探測RS的狀態(tài),在1分鐘內(nèi)自動把故障RS從可服務(wù)列表中踢除,當(dāng)TGW檢測到RS恢復(fù)正常后,自動把它加回可服務(wù)列表中。由TGW提供負(fù)載均衡和容災(zāi)。
?邏輯層
邏輯層使用SPP容器開發(fā),禮包列表/區(qū)服選擇/禮包發(fā)貨三個功能均是無狀態(tài)服務(wù),多個服務(wù)器在服務(wù)容量足夠的情況下任意踢掉一部分都不會影響正常服務(wù),使用L5進行負(fù)載均衡/容災(zāi)/過載保護。
L5:機器級別容災(zāi),業(yè)務(wù)程序調(diào)用L5 API從L5 Agent獲取后臺服務(wù)器的(IP, Port),使用該(IP, Port)對應(yīng)的后臺服務(wù)器進行通信,訪問結(jié)束時調(diào)用L5 API上報訪問接口和處理時延,L5 Agent對L5 API 上報的訪問結(jié)果和處理時延進行統(tǒng)計和上報,當(dāng)服務(wù)器出現(xiàn)故障,L5一般在1到2分鐘內(nèi)就會自動剔除故障服務(wù)器。
?數(shù)據(jù)層
數(shù)據(jù)層主要使用了作為K-V存儲的CMEM和作為分布式消息隊列的RocketMQ,這兩種服務(wù)都采用接入層-存儲層劃分,邏輯層訪問數(shù)據(jù)層的接入層使用L5進行負(fù)載均衡/容災(zāi),數(shù)據(jù)層的存儲層都采用一主一備雙機熱備容災(zāi),并落地磁盤支持掉電重啟后重建內(nèi)存數(shù)據(jù),支持多機容災(zāi)但是不支持多機房多地容災(zāi)。
?過載保護
紅包入口流量說是8W/s,萬一基礎(chǔ)側(cè)有問題發(fā)到了20W/s怎么辦?
每個模塊的容量都是從入口流量按照用戶行為漏斗模型推算轉(zhuǎn)化率設(shè)計的,萬一評估有誤轉(zhuǎn)化率偏高超過了設(shè)計容量怎么辦?
對于可能出現(xiàn)的超過了設(shè)計容量的流量尖峰,就要應(yīng)用過載保護方法,保障系統(tǒng)能拒絕超過容量的部分請求,保障設(shè)計容量內(nèi)的請求還能正常響應(yīng),實施的時候有四個要注意的地方:
-
從源頭上減少無效請求;
-
從接入層開始拒絕;
-
各層互相不信任;
-
要照顧用戶的情緒。
?流量預(yù)加載
CDN做為頁面訪問的關(guān)鍵路徑,前端頁面制作離線包,預(yù)先下發(fā)到客戶端,減少除夕當(dāng)天CDN的流量壓力。
?頻率限制
前臺對用戶發(fā)起請求的頻率進行限制,超出頻率的請求提示用戶失敗而不走到后臺(每5秒只允許請求一次到后臺),前臺保護后臺。
后臺接入層根據(jù)壓測數(shù)據(jù)配置CGI接口的每分鐘接受的請求數(shù),超出接口處理能力的請求丟棄并進行告警。接入門神系統(tǒng),配置IP/uin/refer等規(guī)則限制惡意用戶刷請求,保障服務(wù)的正常運行。
?降級開關(guān)
前臺調(diào)用后臺的接口,設(shè)置開關(guān)以一定概率丟棄請求,對于關(guān)鍵路徑返回錯誤提示用戶稍后重試,對于非關(guān)鍵路徑提供降級體驗,結(jié)合頻率限制功能,可以限制前臺的流量傳遞到后臺的比例,當(dāng)比例設(shè)為0的時候則關(guān)閉該模塊,實現(xiàn)前臺保護后臺。
?隊列堆積丟棄
后臺邏輯層使用SPP框架,worker處理消息前先檢查消息在SPP消息隊列中等待時間是否超出了預(yù)設(shè)閾值(500ms),在隊列中堆積過久的消息前端已經(jīng)超時,對于用戶已經(jīng)無意義,服務(wù)丟棄請求并進行告警,預(yù)防隊列式過載雪崩。
?柔性可用
柔性可用,柔性是為了保護系統(tǒng),保證系統(tǒng)整體的穩(wěn)定性,可用性。可用是為了用戶,盡最大努力為用戶提供優(yōu)質(zhì)的體驗(可能是部分服務(wù)體驗)。一個是從系統(tǒng)本身角度出發(fā),一個是從用戶角度看,在真正實施過程中只有將兩者分析清,并融合在一起才能真正做到系統(tǒng)的柔性可用。關(guān)鍵問題是找準(zhǔn)用戶的核心訴求,找出符合求場景的核心訴求作為關(guān)鍵路徑,出現(xiàn)異常可以放棄的訴求作為非關(guān)鍵路徑。
?找準(zhǔn)用戶的核心訴求
春節(jié)游戲紅包用戶的核心訴求有三個:
-
看到禮包列表
-
選擇區(qū)服角色
-
領(lǐng)取禮包到賬
其他的都可以作為非關(guān)鍵路徑,有可以提高用戶體驗,沒有也不影響用戶的核心訴求。
?保障關(guān)鍵路徑的可用
看到禮包列表:作為頁面關(guān)鍵模塊的禮包列表,在紅包活動前,十種游戲的禮包內(nèi)容作為前端靜態(tài)數(shù)據(jù)已經(jīng)預(yù)先通過離線包/CDN下發(fā)。紅包活動時,后臺接口根據(jù)用戶偏好返回的游戲禮包列表,只是提供前端禮包內(nèi)容進行過濾和排序,失敗了也有前端默認(rèn)的游戲禮包列表,用戶依舊能看到禮包列表,只是排序不夠智能化。
選擇區(qū)服角色:除夕前一周游戲中心的主站頁面和運營活動增加一個后臺接口請求,預(yù)先請求用戶的區(qū)服角色信息緩存到本地,既降低了除夕當(dāng)天的區(qū)服接口請求量又保證了游戲中心核心用戶的區(qū)服信息是有效的。
領(lǐng)取禮包到賬:RocketMQ對于領(lǐng)取操作是關(guān)鍵路徑服務(wù),用戶領(lǐng)取禮包后需要寫入RocketMQ才能算成功。故業(yè)務(wù)對消息隊列做了邏輯層面的容災(zāi),當(dāng)RocketMQ出現(xiàn)故障時,可以打開容災(zāi)開關(guān),領(lǐng)取操作寫完應(yīng)發(fā)流水后直接返回成功,不再往RocketMQ寫入消息,采用分時段對賬的方法替代實時發(fā)貨,達到消息隊列容災(zāi)效果,參見容錯需求開發(fā)。
?放棄異常的非關(guān)鍵路徑
-
前端頁面展示模塊化,對于請求數(shù)據(jù)不成功的非關(guān)鍵模塊進行隱藏。
-
紅包頁面導(dǎo)流到游戲中心,游戲中心展示按紅點邏輯展示,只顯示第一屏的數(shù)據(jù),默認(rèn)不加載第二屏數(shù)據(jù),用戶往下滾動時再加載,犧牲用戶往下滾動會短暫卡頓的體驗減少后臺的請求壓力。
-
后臺讀取算法接口返回的推薦排序失敗時使用默認(rèn)的禮包排序。
-
后臺讀取CMEM接口返回的禮包是拉活躍還是拉新失敗的時每款游戲默認(rèn)返回低價值的拉活躍禮包。
?立體監(jiān)控
“我們對外提供的服務(wù)是否正常的么?怎么證明我們的服務(wù)是沒有問題的?”,是監(jiān)控告警首先要回答的根本問題。有效的監(jiān)控告警需要保證能完備地監(jiān)測業(yè)務(wù)指標(biāo),當(dāng)發(fā)現(xiàn)問題時能有效通知負(fù)責(zé)人并幫助分析問題,強調(diào)的是“完備性”和“有效通知”,兩者缺一不可。春節(jié)紅包的監(jiān)控告警從用戶、業(yè)務(wù)和機器三個層面上描述。
?用戶層面
從用戶的角度監(jiān)控系統(tǒng)是否有問題,模擬用戶行為從系統(tǒng)外部發(fā)起請求,判斷請求結(jié)果和時延是否符合預(yù)期,使用的是ATT的自動化用例。
ATT,autotest,是社交、開放平臺測試組使用的測試管理工具,它是功能用例、自動化用例管理的平臺。通過模擬真實的用戶訪問并校驗返回數(shù)據(jù),確認(rèn)訪問延時、功能正確性的用戶層的監(jiān)控手段,從業(yè)務(wù)側(cè)進行實施監(jiān)控功能的正常運行狀態(tài)的工具。
?業(yè)務(wù)層面
監(jiān)控紅包系統(tǒng)內(nèi)部的各個子業(yè)務(wù)模塊是否運行正常,分為兩種:
1. 模塊間的調(diào)用監(jiān)控
監(jiān)控系統(tǒng)內(nèi)部各個模塊間的調(diào)用是否正常,使用的是模調(diào)系統(tǒng)。
2. 模塊內(nèi)的狀態(tài)監(jiān)控
監(jiān)控某個業(yè)務(wù)模塊當(dāng)前的狀態(tài)是否正常,使用的是各個子系統(tǒng)自建的監(jiān)控告警系統(tǒng),春節(jié)紅包這方面的監(jiān)控主要有兩個:AMS禮包領(lǐng)取剩余數(shù)量和消息隊列消息堆積數(shù)量。春節(jié)紅包由于準(zhǔn)備的禮包數(shù)量較為充足,故沒有引起告警;隊列由于生成速度遠超消費速度,設(shè)置的告警閾值是100W,但實際最終堆積超過了1200W,引發(fā)了告警。
?機器層面
監(jiān)控機器的CPU/內(nèi)存/磁盤/網(wǎng)絡(luò)是否正常,使用的是網(wǎng)管系統(tǒng)。
網(wǎng)管系統(tǒng)(TNM2)是一個功能非常強大的采集服務(wù)器CPU、內(nèi)存、網(wǎng)絡(luò)、IO等指標(biāo)的監(jiān)控系統(tǒng),同時還能對設(shè)備的進程和端口異常、磁盤使用率、硬件故障等進行告警,同時對外部系統(tǒng)提供功能豐富的調(diào)用接口,關(guān)于網(wǎng)管系統(tǒng)的監(jiān)控能力,請參考其網(wǎng)站首頁的TMP監(jiān)控能力白皮書 。
演習(xí)驗證
演習(xí)是一種將被動相應(yīng)轉(zhuǎn)換為主動服務(wù)的手段,在演習(xí)前設(shè)定演習(xí)目標(biāo)和演習(xí)方法,在演習(xí)過程中進行驗證并收集數(shù)據(jù),在演習(xí)后進行總結(jié)并提出改進方案。通過演習(xí),可以實際驗證用戶行為與評估預(yù)期是否一致(灰度演習(xí)),系統(tǒng)各個模塊的容量是否符合預(yù)期(壓測演習(xí)),各類容災(zāi)和柔性的措施是否生效(異常演習(xí)),提前發(fā)現(xiàn)架構(gòu)中存在的問題。
?壓測演習(xí)
核心問題:系統(tǒng)能否抗住壓力
細(xì)分又可以劃為兩個問題:
-
對于系統(tǒng)容量內(nèi)的合理請求,系統(tǒng)能否正常處理
-
對于系統(tǒng)容量外的超額請求,系統(tǒng)能否成功丟棄
解決方案:全鏈路壓測和單模塊壓測
最理想的情況是先紅包各個模塊的進行壓測后評估沒有問題,再灰度用戶使用現(xiàn)網(wǎng)流量進入紅包系統(tǒng)進行全鏈路壓測,但由于使用現(xiàn)網(wǎng)流量進行演習(xí)需要實際地發(fā)送紅包,成本較高,灰度500萬用戶紅包入口峰值僅為5k/s,遠低于設(shè)計的80k/s。故對系統(tǒng)的壓力測試驗證主要以單模塊壓測結(jié)合灰度演習(xí)得到的用戶行為數(shù)據(jù)評估系統(tǒng)的整體能力。
對于未上線的接口的CGI Server和SPP Server,采用ApachBenchmark模擬請求壓測。
對于已經(jīng)上線的接口,除了隔離現(xiàn)網(wǎng)機器用ApachBenchmark模擬請求壓測外,還使用了小組自研的壓測系統(tǒng),通過調(diào)整L5權(quán)重把現(xiàn)網(wǎng)流量逐步導(dǎo)到一臺機器上來進行壓測。
經(jīng)驗證,在V8的機器上,禮包列表/區(qū)服接口CGI/Server的QPS在5k/s~8k/s之間,禮包領(lǐng)取接口達到2k/s的QPS。在部署足夠的機器后,對于系統(tǒng)80k/s的請求量,是可以正常處理的。
在配置了接入層CGI的限速選項后,超出限速(8k/s)的超額請求會被CGI直接返回錯誤而不傳遞到后端處理;在配置了邏輯層SPP的超時丟棄后,在隊列中堆積超過超時時間(500ms)的堆積請求會被框架丟棄而不進行實際處理。對于超出系統(tǒng)容量的請求,系統(tǒng)是可以成功丟棄的。
?異常演習(xí)
核心問題:系統(tǒng)發(fā)生異常時各種柔性邏輯/容災(zāi)措施能否生效
系統(tǒng)中的柔性/容災(zāi)措施,往往只有系統(tǒng)異常時才會生效,導(dǎo)致在實際現(xiàn)網(wǎng)服務(wù)運行中,柔性邏輯經(jīng)常無法測試到,容災(zāi)措施一般也不會啟用。這樣,當(dāng)運營環(huán)境真正異常時,柔性邏輯/容災(zāi)措施是否有效還是個未知數(shù)。
解決方案:驗證柔性邏輯和容災(zāi)措施
在紅包正式上線前,通過模擬故障發(fā)生的真實異常場景,列出重點可能發(fā)生的故障問題,驗證柔性邏輯和容災(zāi)錯誤是否真實有效。
-
后臺SPP修改神盾的L5為錯誤的L5,SPP調(diào)用神盾出錯,預(yù)期后臺依舊能按默認(rèn)排序返回禮包列表
-
后臺SPP修改CMEM的L5為錯誤的L5,SPP調(diào)用CMEM出錯,預(yù)期后臺依舊能按全部游戲推薦拉活躍禮包返回禮包列表
-
后臺隨機停掉一臺SPP,CGI調(diào)用SPP出錯,預(yù)期服務(wù)短時間內(nèi)有部分失敗,L5能在1~2分鐘內(nèi)踢掉該出錯機器,服務(wù)恢復(fù)正常
-
打開MQ容災(zāi)開關(guān),用戶領(lǐng)取成功消息不再放入MQ,而是直接走流水對賬,預(yù)期游戲能夠成功到賬
-
前臺用戶操作頻率超過了限制(5次/秒),預(yù)期前臺直接返回領(lǐng)取失敗,抓包看到請求不走到后臺
-
前臺調(diào)用后臺接口通過設(shè)置host指向錯誤IP,前臺調(diào)用后臺推薦接口出錯,預(yù)期前端頁面依然能正確顯示作為關(guān)鍵路徑的禮包列表
-
前臺調(diào)用后臺接口通過設(shè)置host指向錯誤IP,前臺調(diào)用后臺非關(guān)鍵信息接口出錯,預(yù)期前端頁面對非關(guān)鍵模塊進行隱藏
經(jīng)測試同學(xué)驗證,checklist中的柔性邏輯和容災(zāi)措施確切有效,符合預(yù)期。
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/6544418.html
總結(jié)
以上是生活随笔為你收集整理的从技术角度谈一谈,我参与设计开发的手Q春节红包项目--转的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 历经8年双11流量洗礼,淘宝开放平台如何
- 下一篇: 一个创业公司的API网关落地实践--转