我的第6個京東618

經歷過 才知道有多美

今年是我的第6個618,因爲入職的時間比較"合適",使得我經歷了每年兩次完整的大促備戰。那年還在北辰,618的當晚,我記憶的很清晰,接近凌晨1點左右的時候,我們聚集在樓道里面,大家舉杯相慶,來祝賀剛剛平穩度過的大促。從此這樣的場景在每年的這個時候都會經歷一次,激動一次。每一次大促備戰都是一場全兵演練,我們在這個戰鬥過程中,團隊合作、技術實戰、用戶意識上都有一個立體的提升。站在每年的這一刻往前看,一路走過來的卻是好些個不平凡的白天和夜晚。正如我們國家的乒乓球隊在每次國際比賽中都有一個完美的結局,但過程從來不缺乏緊張、風險和刺激。

每逢大促開始前我們都要進行一段時間的備戰準備工作,以保障線上系統平穩度過,那麼我們都“備”什麼呢?

首先確定自己的備戰思路,梳理核心流程,找出薄弱點,對薄弱點進行具體優化,同時協調壓測對優化結果進行驗證。優化和壓測會有一個反覆的過程,後面我們還要實際演練,比如降級開關,防止實際情況發生的時候準備好的功能不可用。最後我們要做一輪培訓,包括工具的使用、快速定位問題的方法、歷來的教訓總結。從心理層面上我們也要進行輔導,大促期間發生的問題都不是小問題,研發人員在這種壓力下處理問題的心態會有很大波動以致動作變形,我們會在這方面做一次心理疏解。我們可以利用幾個規則來協助我們的備戰工作,比如二八法則,找出20%重要核心的功能,在找薄弱點的時候我們可以試試墨菲定律的幾點規則——可能出錯的事總會出錯,如果你擔心某種情況發生,那麼它就有可能發生。最後我們還會一起列出心中最不可能出現問題的系統和功能點,重點對待列出來的問題。下圖是一個備戰流程的示例圖。

我們常用的備戰技術肯定不是重啓、回滾、加機器。這裏面筆者總結有分離技術、緩存技術、SQL優化、快速失敗、降級限流和臨近管控。

分離技術

話說天下大勢,分久必合,合久必分,但在軟件架構領域,從最早的集羣部署到分佈式部署再到微服務架構,一直是一個分的趨勢。比如一個開放平臺提供了ISV的服務、自有客戶端的服務、其他平臺的服務,同時還有監控服務、日誌服務、消息服務等,需要將業務和服務隔離部署,線下分析和線上運行隔離。同時還可以採取線程池隔離,比如在RPC框架中的服務端爲每個不同重要程度的服務各自分配一個線程池的方式。數據庫層面上實現主從分離,大多數平臺的業務都是讀多寫少,可以充分利用分庫的資源。還可以再將數據庫細分,按照主要業務拆分不同的數據庫,結合RPC,降低數據庫層面的耦合程度。

緩存技術

如果軟件裏面真的有一種銀彈的話,那麼我認爲就是緩存,當性能優化遇到瓶頸的時候,當想抗量的時候,我們都會想到緩存。這裏有一個鐵律,那就是對外暴露的接口一定不能直達數據庫。我們常用的緩存是Redis+JVMCache計算Redis穿透率的時候可以通過方法調用實時監控來實現,在一個方法的總入口埋點,比如統計出1分鐘調用M次請求,在請求Redis的入口埋點,統計出1分鐘調用N次請求,計算命中率:N/M在使用Redis的時候要注意含有大數值的key,常常量一大則會造成Redis集羣的熱點訪問,直接將單一節點打死這樣的情況下我們就要拆分大key同時將緩存DB化,也就是不設置超時時間,全部用Redis來抗量。本地緩存常用的有Guava-cache,通過本地緩存可以做三級防護,或者做託底數據等。如果數據尺寸較小高頻的讀取操作變更操作較少,那麼使用這種嵌入式緩存將非常合適。

SQL優化

每次大促前我們都要將系統中性能慢的SQL“出來,而且這種工作投入產出比極高,也就是可以花費較小代價帶來極大的性能收益。SQL性能問題在大多數情況下都是沒有索引引起的,這可能是後續業務變化迅速,上線前代碼review的遺漏,需要在這個時候統一過一遍。還有就是索引使用錯誤引起的,比如索引字段是字符串類型,但程序中請求DB的時候傳的是Long類型,索引失效,表中數量過多,做了一次全表掃描,性能會很差。我們添加索引的時候要看區分度,計算索引區分度的方法:不重複的索引值/總記錄數。值越接近1,說明區分度越高,查詢的時候MySQL就會過濾掉更多的行數據。還有,添加索引最好結合MySQL執行計劃來進行判斷。有時候做了過多的join操作,比如超過3張表以上,我們就要想着去拆解這些SQL語句。在數據庫層面可以把歷史數據轉出以減少數據量從而實現提高查詢速度的目的。

快速失敗

快速失敗策略實際上是一種自我保護措施,比如調用第三方接口超時,如果超時時間設置過長,那麼在訪問量大的時候,就會導致請求線程積壓。如果此時有線程隔離還好,若剛好沒有,那麼訪問量一上來就會迅速導致CPU使用率飆高。比如網關係統的特點之一是會大量調用第三方接口服務,我們會對每個方法動態地設置超時時間,如果有接口方法報警,再結合JVM性能數據,我們會將這個接口的超時時間閾值調小。通過ZooKeeper下發到每一個服務節點上。在大促前,我們會重點檢查MySQLRedisRPC等框架的RPC調用超時設置,確保每一次RPC調用都要有上限閾值。關於RPC調用超時,這裏多說一下,有時候我們會發現調用端響應性能比如超過500ms,但服務端卻是在100ms除了檢查網絡延時、TCP重傳的次數,還要注意一點任何一個成熟的RPC框架都不會讓業務線程直接參與網絡請求,RPC會提供一個消息隊列,調用端直接跟消息隊列打交道。此時,我們就要想到隊列這塊是否有問題了。

降級限流

這種技術實際上是保命的措施,降級一般有屛蔽降級和容錯降級兩種。一些非核心的功能,比如系統的公告、服務號、論壇等功能,而它們恰恰又請求MySQLRedis等公共資源,爲了減少這種競爭,我們就會對這些功能進行屛蔽降級,直接切斷RPC調用,不再發起遠程調用,返回空或其他異常提示,減少公共資源的訪問。容錯降級是一種放通,不會像屛蔽降級那樣暴力,往往會有託底措施以保證用戶有更好的體驗,比如我們常用的本地緩存數據等。再說一下降級開關,當線上需要降級的時候,要能夠秒級切換,可以採用統一配置中心來實現。同樣,限流技術在平臺中也是異常重要的一個措施,尤其是對網關的調用。可以採用令牌桶的方法,實現方式是GuavaRateLimter,簡單有效,再結合統一配置中心,可以動態地調整限流閾值。不用重啓服務器即可實現快速限流策略的調整。在網關裏面還有一個設置,那就是併發度,這個是方法粒度的,對每一個調用第三方的接口都有一個併發度數值的設置,而且是動態設置,也是通過ZooKeeper下發到每一個服務節點上的。併發度具體是通過JDKSemaphore實現的。

性能壓測

性能壓測可以很好地檢驗優化的結果,壓測的過程中我們關注QPS的同時,還要結合服務器的CPUI/O、內存等機器性能指標來定位性能瓶頸。最後預估系統的承載能力,提供數據支撐來申請服務器或Docker資源。壓測工具研發可以自己寫腳本,藉助JmeterLoadRunner等工具實現,也可以有計劃地聯繫性能壓測組協助執行。最困難的還是產生真實的壓力。

 

另外還有一個備戰點,返璞歸真,回到代碼,重點檢查一遍核心功能,把壞味道的代碼查出來。比如“join”了很多張表的SQL語句,日誌輸出沒有采用條件方式或佔位符的方式,日誌重複打印,try代碼塊放到了事務中,循環體中含有低性能的語句,鎖代碼塊中進行RPC調用,等等。

總結歷次的大促,主要是工具、知識、經驗三個方面的備戰。工欲善其事,必先利其器,我們要有一些個好的工具來輔助我們解決問題,比如監控CPU、網絡的工具,監控方法性能的工具,等等。知識層面是我們歷來的積累、我們認識的提高、使用工具時的指導。經驗是我們以往的大大小小的教訓的總結、前車之鑑,防止我們再次發生類似的事情。

 

臨近管控

前幾天,我們的歐指導還在內部備戰例會上強調過一個事情,如果某個機房機器的網卡出現故障甚至某個機房整個網絡出現故障,應該如何應對,當然第一時間是要把流量切走。那麼如何第一時間發現這種網絡故障呢,就是添加監控比如TCP重傳次數報警。類似,如果依賴的某一個RPC接口出現訪問異常,應該如何第一時間知道呢,也是添加監控比如性能和可用率監控。如果一個域名訪問出現異常,應該如何第一時間知道呢,仍然是添加監控比如URL存活報警監控。那麼從一個月前開始備戰到現在臨近大戰來臨,在臨近的這段時間我們能做的而且最有效的管控措施就是對監控的差缺補漏。我們稱之爲臨近管控。很多次的故障覆盤告訴我們,幾乎每次的故障排查阻礙都是因爲監控粒度不夠,這裏面不僅僅只包含監控報警,還有日誌的打印清晰以便幫助最快定位問題並解決。

"不謀全局者,不足謀一域",每次備戰開始商家研發部都會做好頂層設計,保持步伐一致,堅持"書同文、車同軌、行同倫"在每一次梳理系統過程中發現的問題上,我們都嘗試多種不同的解法,無論是新技術還是成熟的解決方案,我們都充分驗證,直至完全掌握,不放過一絲遺憾,力促平穩頂過每一次的流量衝擊。記得去年JOS開放網關開始備戰618的時候,我們要解決一個調用方和接口提供方性能不對等的問題,大家一起封閉在會議室,從監控工具的使用、代碼底層IO通訊的原理、日誌打印的性能各個角度去分析,連續奮戰五天,最終攻克這一性能問題,讓我們商家的響應速度提高了足足5倍。這樣的場景還可以列舉很多,不過在我看來,最寶貴的並不是我們最終採用某種技術或方案的決定,而是大家在一起探索,深入到問題解決過程中積累起的經驗和我們磨合形成的這種大促戰鬥中的"齒輪咬合感"從基礎架構到系統的每一行代碼的優化,我們不斷地顛覆技術瓶頸,不斷創新以適應不斷增長的需求。此時此刻,備,全面充分;戰,來比擒獲!

 

本文部分內容摘自新書《架構修煉之道》第9章容錯之道中的 "大促備戰都備什麼" 一節。

發佈了87 篇原創文章 · 獲贊 30 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章