阿里专家梁笑:2018双十一下单成功率99.9%!供应链服务平台如何迎接大促
本篇文章來自于2018年12月22日舉辦的《阿里云棲開發者沙龍—Java技術專場》,梁笑專家是該專場第一位演講的嘉賓,本篇文章是根據梁笑專家在《阿里云棲開發者沙龍—Java技術專場》的演講視頻以及PPT整理而成。
摘要:2018年雙十一平穩度過,海量訂單、零點流量高峰,阿里是如何實現供應鏈99.9%的下單成功率?本次分享中,阿里2018年雙十一大促供應鏈服務保障平臺負責人向大家詳細闡述大促前4個月的全程經歷。面對大促第一步需要做什么,流量峰值如何評估,性能優化從何處著手,一套有條不紊的供應鏈服務平臺迎接大促的解決方案至關重要。
?
演講嘉賓簡介:
梁笑,阿里新零售供應鏈平臺事業部,擅長 Java、Spring、OOP、分布式、架構設計,參與過供應鏈服務決策平臺、雙十一大促等項目,對業務開發、大促保障、架構設計等有所涉獵。
?
本次直播視頻精彩回顧,戳這里!
PPT下載地址:https://yq.aliyun.com/download/3183
以下內容根據演講嘉賓視頻分享以及PPT整理而成。
?
本文圍繞雙十一大促歷程,從以下幾方面介紹供應鏈服務平臺如何迎接大促:
1. 概述
2. 梳理鏈路
3. 峰值評估
4. 容量評估
5. 性能優化
6. 依賴改造
7. 保障協同
8. 壓測檢驗
9. 項目協同
10. 監控治理
11. 戰前準備
12. 總結
?
一、概述
大家熟悉的供應鏈服務包括庫存控制、計劃調撥等,這里介紹的供應鏈服務更偏向于交易側。例如在淘寶或天貓購買物品時,會有今日下單預計某日送達等物流提示,這種物流時效承諾即是由供應鏈服務平臺提供。再如,購買電冰箱、空調等大件需要預約配送時,需要選擇指定的配送商或者貨到付款、拆單合單等物流透出,都需要供應鏈服務平臺的支持。除了這些大家作為消費者可以直觀感受到的服務外,商家的商品入庫發貨等操作也都離不開供應鏈服務平臺。因為大促時物流服務需要實時透出,服務平臺是需迎接雙十一實時下單的高流量的,此外服務平臺還需要承接物流發貨的服務透出,例如發貨的倉庫、路線、發貨時效及服務等。因此,供應鏈服務平臺在阿里體系中扮演了一個上承交易、下接物流的腰部力量,主要包括物流服務、物流透出、商家訂購、容量管控等功能。物流服務及物流透出上述已提及,商家訂購包含倉訂購和快遞資源訂購,容量管控是指物流干線的容量能力,例如從北京到上海,可以在當日送達的物流能力為一千單,超過一千單外的便無法達到這樣的物流時效訴求。至此,大家應大致了解了供應鏈服務平臺的概念。
供應鏈服務平臺保障的過程如下圖所示:
?
如何在業務容量峰值時保障系統,該采取哪些措施,這是一個不小的挑戰。首先,需要分析出哪些接口需要重點保障,哪些薄弱點或性能低下的鏈路需要重點評估。接下來,需要對這些進行優化操作。然后,對優化后的接口通過自測或壓測進行驗證。驗證過程中可能會發現,已有的問題解決了但是出現了新的問題,這就需要再次分析優化。這是個螺旋上升形的過程。上圖右側是保障過程的階段描述,會在接下來進行詳細闡釋。
?
二、梳理鏈路
如果給你一個系統,在你不了解的情況下,讓你在流量峰值下保障系統的穩定性,首先你需要明確要做的事情,清晰目標任務的范圍。因此,第一步就是梳理系統業務的鏈路,對系統有宏觀全面的認識,這是保障大促穩定性的前提。但是,以服務平臺的現狀來說,有以下幾個通病:祖傳代碼、上古應用、文檔缺失、無人可問。阿里的服務平臺自2011年開始經歷過三次較大的升級改造,每次升級大部分核心功能會下架升級,但仍有某些小功能無法改造。這就造成在2018年的大促保障時還需要閱讀2011或2012年的代碼,甚至某些應用都無法打印日志。文檔缺失、無人可問也使系統保障更加困難。
梳理鏈路可以分為以下四步進行:
1. 梳理對外接口。在日常開發中,主要的業務邏輯代碼大約包含四五個對外接口,但是通常來說實際會比這要多。在對服務平臺的鏈路梳理中,新老三版系統包含大約80多個對外接口。但在實際工作中,只會涉及十個接口左右。可見,這些接口存在巨大的冗余。某些接口可能已不再使用,或某些接口有使用者,但使用者并沒有意識到在調用該接口。因此,梳理對外接口就是梳理出接口是否在實際提供服務。
2. 移除無用接口。在剩下的70多個接口中,一定有無用的部分,移除這些接口也是移除了潛在的bug出現。這可以通過查看調用者、分析流量或者咨詢使用者來進行移除。在這個階段,阿里的供應鏈服務系統大約下架了近40個廢接口,如此大幅縮小了需要保障的系統范圍。
3. 梳理剩余接口。這個階段中將各接口按照重要性進行保障力度的劃分,例如某些接口是需要重點保障的,而某些接口無需重點保障,不應占用寶貴的機器資源、數據庫資源等,例如一些查詢功能的端頁面,在大促時出現問題也不會產生重大影響。
4. 確認強弱依賴。對劃分出的需要重點保障的接口需再次梳理出相互間的強弱依賴關系,這就需要理清系統的業務邏輯。例如在阿里的大促系統中,如果庫存出現問題,那么緊接其后的訂單、配送等接口也都會混亂,這便是一個強依賴過程。因此,這里應設置成如果庫存出現問題,下單只能返回失敗。弱依賴過程則不同,例如根據歷史數據得知某消費者經常使用某一個自提站點,如果在大促中,自提站點的鏈路掛掉,分配的不是這個自提點,雖然這可能會導致消費者的愉悅感下降,但下單過程不會產生太大的問題。此外,還需對接口的調用量和調用比例進行統計梳理,例如調用一次A接口,可能會在下游調用一次或若干次B或C接口,通過這個比例可以根據A接口流量的增長幅度計算下游的接口流量。
如此梳理完成后便可以產出一份鏈路文檔,大致掌握了需要重點保障的部分、可能的調用方、可能的消費者、消費的量級、涉及的數據庫、緩存中間件、鏈路的強弱依賴等信息,這是后續工作的綱領性文件。
?
三、峰值評估
在有了這份綱領性文件之后,則需要明確任務目標。對這樣實時下單的強依賴系統來說,最直觀的的目標是要支撐住雙十一零點的交易峰值。這就需要評估這個交易峰值是多少,畢竟每個系統被核心的交易系統調用的頻率并不相同。峰值可以根據交易下單量、業務預測和歷史經驗來進行評估。交易下單量相對來說確定性較高,因為這在系統內部可以通過限流解決。當下單量超出了系統的承受力,則直接返回下單失敗,讓消費者再次下單即可。因此每秒的最高下單量是相對確定的值。業務預測是指對每個行業線的下單量進行預測。即使知道每秒的下單總量,卻無法知道例如天貓超市或者某個行業線的細化下單量,那么便收集該行業線下的店鋪信息,再根據一些專業知識進行評估。這樣的業務預測值是缺少瞬值的,例如它可能可以預測出一天的單量,但無法預測0點那一秒的單量。因此,還是需要根據歷史經驗來彌補這個缺陷。例如根據前三年的大促流量分布、雙十一前的三八大促九九大促流量分布等數據,進行流量預估得到流量漏斗。甚至在大促前,對某些鏈路進行了改造變更等操作的,也需要在流量預估的過程中詳盡考慮。由上述可見,在這樣輸入有限的情況下,需要抽絲剝繭得出一份可能性較高的峰值評估。
這樣的峰值評估主要為兩方面,如下圖所示。一部分是接口峰值,這會用于指導保障整個系統。例如若下單量為十萬,那么商品詳情接口大約會產生三十萬流量,渲染下單接口十二萬到十五萬,真正下單扣減約七到八萬,這些值會指導進行系統下單時的重點保障。另一部分是行業峰值。例如下單量為十萬時,快消品牌和美妝產品各自的單量為多少,這會直接顯示出系統各行業所需要的下單承受能力。
?
四、容量評估
確定了任務目標后,就需要評估現有的機器容量是否可以支撐預估的流量峰值。阿里的供應鏈服務平臺是一個單元化的應用,可以理解為一個跨城市跨機房的異地部署過程。每個單元(機房)有不同的流量承受能力,例如可以在華北設立機房承受30%流量,華南機房承受30%流量,華東機房承受40%流量。接著通過壓測等方法可以方便的得出單機性能,測試出健康情況下單機的QPS流量。例如,UNSZ(深圳單元)需要承擔6.52%的流量,結合單機性能預估需要的機器數量,根據比例得出預估QPS值。接下來需要考慮,現有的機器能滿足預估狀況嘛?是否有缺口?如果存在缺口,是可以通過優化還是申請預算解決呢?最短的木板(壓力最大的部分)是哪里?因為各個機房的實際性能存在差異,這部分差異也需要考慮在內。根據最短木板確定限流保護值,重點保障最危險的單元。此外,在容量評估時,最好預留一定的buffer,保障可能超出的流量。
?
五、性能優化
基于已有的機器預算,和之前梳理出的接口鏈路,接下來需要一些手段優化性能來支持峰值流量。不僅包括對古老代碼的優化,也需要對新產生的代碼進行改進。下圖展示了供應鏈服務平臺的大促性能優化中采取的主要手段:
這些細節化手段這里不再贅述,大家可以參考一些web技術文檔即可了解,這里重點為大家介紹如何梳理上述優化過程。沒有一個整體的方法論,貿然入手消耗的精力暫且不談,達到的效果可能也不盡人意。這些優化手段主要通過分析阿里的業務特點及雙十一的玩法特點得出。例如,若某一地區的倉配產能不高,無法實現物流時效承諾,那么撤下物流時效承諾的同時,與其相關的鏈路也可以一同撤下,這便大大提升了這一塊的性能。因此,提升性能不只是通過內存調優等,也可以根據業務邏輯來調整。優化的各個步驟如下:
1. 減少流量。在客戶端或服務端屏蔽流量,降低不必要的調用,這樣的性能優化效果最為可觀。
2. 移除或降級IO。根據業務需求盡可能的下線無用的IO邏輯或者根據業務特點降級部分IO。
3. 減少IO調用。例如在貨品查詢IO中,可能會采用多個for循環來進行查詢,那么便可以采用批量查詢來代替單個查詢。
4. 移除本地IO。移除和檢查沒用的日志和濫用的日志。某些debug代碼在平時產生的流量不會引起大家注意,但是在全鏈路壓測驗證時就可能產生非常多流量以致線程卡住。
5. 使用緩存。短時間內數據不變的情況下,進行緩存,避免多余的IO。這種方式在大促時效果尤為明顯。在電商行業,類似某個店鋪與貨品的綁定關系在大促時間內基本不會變化,這種不變的數據使用緩存效果最佳。
6. 緩存命中率。在平時緩存可能設定失效時間為幾十分鐘,但是大促時可以禁止該類影響穩定性的操作,將失效時間設置為幾個小時甚至十幾小時。拉長緩存失效時間,可以極大的提高緩存命中率,平時的命中率大約在60%-70%左右,在大促時這個數據提升到了99.99%。此外,還需要充分預熱。
7. 緩存吞吐。除了本地緩存外,大家可能都會使用遠程緩存,例如redis等。阿里巴巴使用tair緩存,對其序列化方式進行了修改。java自帶的序列化方式性能較差,得到的序列化對象也字節較大,因此將其改成了Hessian方式(沒有選擇kryo或protobuf是因為當時轉換成Hessian方式最為簡便)。同時精簡字段,假設某個返回對象有十個字段,但對外接口只需使用兩三個。大家知道,帶寬一定的情況下,單個數據量越大,同時能通行的數據就越少。流量峰值時,帶寬通常都會比較緊張,那么便無需將剩下的廢字段也存入緩存。進行了上述改進,緩存的吞吐有了很大程度的好轉。
8. 本地緩存。盡量使用本地緩存在tair前擋一層,避免網絡IO。本地緩存不可能存太多,但是在某些極限情況,例如卡券類或紅包等,當天調用極其頻繁并且不會變化,這樣的數據可以緩存在堆外內存中。
9. 數據庫。在解決了數據IO的大部分問題后,便可以采取一些更細致的優化手段。例如檢查慢的SQL,索引使用是否正確,有沒有離線拖庫任務,是否可以清理一些碎片等。
10. 本地代碼。去掉高頻率低效的本地代碼。但根據經驗,這種手段得到的優化效果有限。
因此,縱觀整個優化思路,減少IO和使用緩存是優化性能的效果較為明顯的方法。
?
六、依賴改造
在性能優化后,大致不會在峰值時出現宕機的情況,但仍需要進行強弱依賴的改造,即強依賴改為弱依賴,弱依賴改為強依賴。強依賴是指如果對兄弟系統、數據庫或緩存的調用出現問題,那么流程直接中斷。弱依賴指即使這部分宕掉,可以直接設置超時或者熔斷,并不會影響流程的后續。強弱依賴的改造其實是一個兜底的過程。將某些錯誤的強依賴改為弱依賴,使其不會影響核心流程,防止雪崩。其次,將一些弱依賴改為強依賴。第一種是確定性的依賴更改。例如如果下單成功需要將扣減庫存數量,如果庫存數量沒有扣減成功,會導致后續各種問題,如果之前采用的措施是將這個異常catch住繼續后面的流程,那么這里就需要更改為拋出異常阻斷流程。第二種是下游重依賴的數據。第三種是可能會造成資損的數據。強弱依賴更改實際上就是對業務負責和保障的過程。
?
七、保障協同
作為系統的負責人,做到上述性能優化等工作對本系統來說足夠了,但是其他兄弟系統的保障協同也是重要的一環。在阿里,每次中間件大規模要求升級時,大促也就近了。供應鏈服務平臺重度依賴的其他系統,例如商品中心、庫存中心、訂購中心和容量中心等也各自針對大促做了不同程度的優化。例如商品中心預熱手段發生了變化,重點流量做出分組操作,并專門留出了部分機器給服務平臺系統做流量分割。庫存中心升級了新模型,改進了緩存等,那么服務平臺系統也需要針對這部分進行相應的協同。和訂購中心的協同主要在預熱和防雪崩,假如宕掉時間過長,就避免調用數據庫,而去調用緩存。容量中心之前只支持單個扣減, 現在可以支持批量扣減,或者修改了表結構。這些兄弟系統諸如此類的優化也從側面使得服務平臺更加健康。
?
八、壓測檢驗
完成優化和協同保障后,當然需要壓測檢驗。在雙十一期間總共經歷12次全鏈路壓測,因為無法再造一個全鏈路系統,所以只能使用真實系統壓測。為了不影響真實系統的運行和消費者的感觀,壓測通常在半夜進行。在壓測過程中,發現了不少問題,這里舉出以下三個例子:
1. 本地線程池滿。jstack查看線程堆棧時,發現很多線程卡在logback輸出日志的地方。查看源碼后發現是使用log.error打印了一個很大的JSON對象,且每次調用都會打印,這就造成本地線程池立刻滿了。因為系統較老,依靠個人的代碼review無法發現此類問題,這就需要壓測這種真實的流量手段來發現。
2. 超時請求。鷹眼(阿里全鏈路監控系統)發現有一個長達3s的請求,一般請求為毫秒級別,檢查后發現是該部分數據緩存未預熱,查詢數據庫超時引起。因為該部分數據在大促時不會調用,因此在壓測時是可以提前將其撤下的。但在壓測時出現這個問題可能會影響到其他業務的穩定。
3. Jmap超時。阿里的服務平臺通過手工執行jmap命令觸發GC來釋放內存,發現在執行jmap時(會先下線對應服務),對應的機器仍然對外服務,并且大多超時。查看了對應的下線腳本后發現,由于鏡像升級,導致Linux命令輸出與老腳本預期不一致。這也影響了線上服務的穩定。
上述問題只有壓測驗證才會檢查出來,因此,壓測的意義不容置否。每一次壓測都是對上一輪優化結果的驗證,同時,每次壓測發現的問題,也是下一次優化的主要方向。
?
九、項目協同
服務平臺內部的工作同事便有10人左右,更要包括對外的例如中間件的部門、依賴和被依賴的兄弟系統部門。人員眾多導致各種協同問題的產生,這就需要一個協同機制。需要明確每個項目的負責人,有固定的聯系方式。任務拆解要細致,每個部分的任務交給指定的人解決。另外需要文檔沉淀,得出的文檔不僅是這次大促的回顧總結,也是下次大促的一個參考。2018年的大促能夠完成,也是依靠了之前的多次大促經驗文檔。驗證考核也必不可少,驗證此次的優化是否達到了設定的目標。某些在測試時沒有顯現出的問題會在真實的流量下被發現,因此事后的驗證考核會幫助發現更潛在的bug。最后,風險識別,某些問題可能因為歷史原因無法修復,那么這種問題要識別出來,和業務人員或產品人員共同找一個可以彌補的方法。例如可以將由于這個bug產生的問題訂單使用工具單獨拋出,再行安排。這些都是作為一個項目PM需要注意的重點。當然,如果能有一個項目間供大家face to face探討各種問題是最好了。
?
十、監控治理
傳統意義上的監控治理有兩個訴求:看圖和告警。看圖主要關注各類曲線是否有波動是否穩定等,告警是在產生問題時可以通過短信、郵件等方式告知。除去傳統的系統監控指標,例如GC次數、內存使用率、QPS高低、系統反應時間,還需要業務監控,這需要通過日志或離線采集進行統計,如此才能對系統和業務都有直觀的認識。當然,“會出錯的事總會出錯”,過程中難免會出現問題。如果出現問題,則需要及時統計產生影響的商家數量、單量、消費者數量,以便后續緊急處理,采取拉單、擴容或下線服務等手段防止過大損失,這便是消防處理。
?
十一、戰前準備
所有優化和監控措施完成后,大促開始前1-2天,按部就班執行各類計劃動作。首先是執行前置預案,例如下線了某些業務鏈路要執行觀察效果。其次是預熱,在大促前一天將一切準備就緒,準備迎接峰值流量。接著進行一致性檢查,單元化的核心應用涉及到成千的機器,可以通過計算MD5校驗值,來確保所有的機器上的zip、jar、war包等是一致的。然后資源檢查,對于大促當天的數據庫、機器、中間件、內存等資源做一個檢查,確保資源到位。清理數據庫,如壓測使用后廢棄的表可以刪除。最后,jmap釋放內存,將可能會觸發GC的內存全部釋放。
?
十二、總結
回顧整個大促過程,今年的供應鏈服務平臺比去年更加穩定,核心下單鏈路成功率接近99.9%,沒有發生限流等嚴重影響用戶體驗的情況。從8月開始思考雙十一的籌備工作,整個大促保障期間,涉及到眾多的系統、人員和業務,每個系統和業務分別由不同的團隊負責,需要做鏈路分析、模型分析、容量評估、目標評估,要協調和明確各節點間的職責劃分、要做各類優化、壓測、監控和反饋等等,持續了長達三四個月。
“這個過程是一次人與人、人與對象間的碰撞,精密的儀器產生完美的作品。”
?
原文鏈接
本文為云棲社區原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的阿里专家梁笑:2018双十一下单成功率99.9%!供应链服务平台如何迎接大促的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何使用阿里云ARMS轻松重现用户浏览器
- 下一篇: 专访阿里云专有云马劲,一个理性的理想主义