618 大促來襲,淺談如何做好大促備戰

作者:泮聖偉(十眠)

如何有效利用雲產品做好我們的業務大促備戰,這是一個大家都比較關心的問題。今天趁着 618 大促來襲前,談一談我們所積累的最佳實踐。

點擊下方鏈接,立即查看視頻講解!

https://yqh.aliyun.com/live/detail/28697

大促的不確定性挑戰

1.png

上圖是我們的一個業務大圖,大促時候我們會碰到許多的不確定性因素的挑戰,如流量不確定,用戶行爲不確定,安全攻擊不確定,研發變更風險不確定,故障影響不確定。最好的方式從入口模擬和防護,但是這麼來看其實是不能解決所有問題,所以需要 IDC 內部進一步做故障演練和流量防護。

因爲流量不確定,所以我們需要容量評估以及業務評估確定流量峯值然後通過限流將流量變成確定性的條件;用戶行爲不確定,所以我們需要通過仿真、多個場景模擬用戶行爲進行壓測與演練,我們需要做到更加真實的仿真並且及時發現系統的瓶頸與優化點,並及時優化;安全攻擊的不確定性,我們需要網關有 waf 防護的能力,比如黑產刷單流量我們如何識別並且通過流控限制其訪問量,從而保護正常用戶的流量;關於研發變更風險的不確定,我們需要通過變更管控來限制大促時進行不必要的變更;因爲擔心出故障時影響面的不確定性,所以我們需要通過不斷的故障演練來錘鍊我們的系統,瞭解故障的影響面並且儘可能控制問題的影響面,避免系統雪崩的問題出現;大促是一個項目,備戰的方法論是把大促不確定性變成確定性,希望能有一些方法論提供給大家,配合我們產品的最佳實踐幫助到大家。

目標確定

大促的目標有很多,比如支撐 XX 的流量峯值,30% 的成本優化,流暢的用戶體驗等。大促備戰的目標在技術同學看來一般圍繞成本、效率、穩定性。成本我們考慮到 Nacos、雲原生網關的資源成本,以及應用的機器數量,利用好 K8s 的彈性能力保證穩定性與成本的一個平衡;在效率方面 PTS 全鏈路壓測提供了開箱即用的全鏈路壓測工具,最接近用戶的仿真壓測流量,可以極大地提升效率,同時 MSE Switch 能力提供了動態配置能力幫助預案的使用;在穩定性方面,MSE 服務治理提供了端到端的流量控制能力,以及彈性過程中的無損上下線能力保證大促過程中的流量平滑無損;同時我們可以配合 MSE 服務治理的全鏈路灰度能力,使用測試流量進行全鏈路的功能預演,儘早暴露問題點。

2.png

備戰流程

簡單來說,大促備戰流程需要關心以下四個點:容量評估、預案准備、預熱、限流。將以下這些點都做到了,就可以把不確定因素都變成了確定性的條件,那麼即使是面對大促的流量洪峯,整個系統會非常的平穩。

容量評估

容量評估的目的爲了實現成本與穩定性的最佳平衡,因此我們需要基於大促的應用表現,確定我們的應用在一定的業務條件下的性能基線;同時另一方面出於成本優化的目標,我們需要確定機器的成本預算。

  • 通過性能評估以及性能優化,確保應用的性能
  • 評估業務變化以及系統的變化
  • 基於業務模型評估,確定全鏈路壓測模型,並進行全鏈路壓測驗收
  • 評估容量的極限水位,保持 60% 的容量水位,開啓彈性擴縮容能力。

3.png

  • 性能評估

首先需要通過 PTS 平臺對服務進行壓測,摸清系統對外核心接口的服務能力以及相應的系統水位。阿里雲產品關於壓測以及全鏈路壓測首推的就是 PTS。

PTS 對比一般的壓測工具,具有以下優勢:

優勢一:功能強大

  • 全 SaaS 化形態,無需額外安裝和部署。
  • 0 安裝的雲端錄製器,更適合移動端 APP 場景。
  • 數據工廠功能,0 編碼實現壓測的 API/URL 的請求參數格式化。
  • 複雜場景的全可視化編排,支持登錄態共享、參數傳遞、業務斷言,同時可擴展的指令功能支持多形態的思考時間、流量蓄洪等。
  • 獨創的 RPS /併發多壓測模式。
  • 流量支持動態秒級調整,百萬 QPS 亦可瞬時脈衝。
  • 強大的報表功能,將壓測客戶端的實時數據做多維度細分展示和統計,同時自動生成報告供查閱和導出。
  • 壓測 API/場景均可調試,壓測過程提供日誌明細查詢。

**優勢二:流量真實

  • 流量來源於全國上百城市覆蓋各運營商(可拓展至海外),真實模擬最終用戶的流量來源,相應的報表、數據更接近用戶真實體感。
  • 施壓能力無上限,最高支持千萬 RPS 的壓測流量。

當性能壓測出系統瓶頸後,我們需要分層次地對系統進行優化。

  • 業務以及系統的變化

評估每次大促相比之前(如果有參考的話)的穩定性評估,以及業務動向,這次業務相比之前是否有量級的提升,業務的玩法是否有變化比如 618 的預售以及搶紅包、滿減等業務玩法是否會對系統造成穩定性的風險,對用戶動向進行分析,從全局視角看系統的關鍵路徑,保障核心業務,梳理強弱依賴。

  • 基於業務模型評估,確定全鏈路壓測模型,並進行全鏈路壓測驗收\

4.png

要發起一次性能壓測,首先需要創建一個壓測場景。一個壓測場景包含一個或多個並行的業務(即串聯鏈路),每個業務包含一個或多個串行的請求(即 API)。

5.png

6.png

通過壓測可以對我們的系統做好一個風險識別與性能管理的目的,通過全鏈路壓測可以提前發現系統的瓶頸,識別性能風險,防止系統的性能腐化。

  • 雲產品的資源容量評估與參考

  • MSE Nacos 容量參考

7.png

評估 Nacos 註冊配置中心水位我們可以從連接數、服務數來評估,有些應用可能服務數特別多,再加上大促時候流量徒增使得應用動態擴容,隨着 Pod 數增加,連接數、服務提供者數量也會線性增加,因此大促前保證  60% 以內的水位是必要的。

  • MSE 網關 容量參考

7(1).png

評估網關水位最直觀的就是按照 CPU 來判斷,建議 30%,最高不超過 60%。爲什麼定的這麼低?參考水位是根據集團內部網關運維經驗給的,網關經常會有些突發流量,尤其對於電商類業務,例如大促、秒殺等,還有要考慮流量攻擊的因素,例如 ddos 攻擊等,網關不能根據 CPU 跑 80%、90% 這樣評估容量,一旦有突發情況網關就很容易被打滿。阿里內部網關比較極端,網關 CPU 一般會控制在 10% 以下。同時還有一些因素,網關突發流量一般都是瞬時的,有可能網關瞬時 CPU 已經被打到很高了,但是監控平均後不是很高,因此網關的秒級監控能力也是非常必要的。

預案

一句話來描述就是有意識地爲潛在或者有可能出現的風險制定應對處理方案。

比如很多影響用戶體驗、性能的開關,一些日常爲了觀察分析用戶行爲的埋點等一些與業務無關的功能,我們在大促的時候都是需要通過預案平臺關閉掉這些功能,當然預案還有一些業務流量相關的預案,涉及到流控、限流、降級後面會詳細介紹。

預熱

爲什麼要做預熱?跟我們的流量模型有關,很多時候我們的流量模型是自然上去慢慢的下來。但大促的時候可不是這樣,流量可能突然暴漲幾十倍,然後維持住,慢慢下來。預熱要預熱什麼?我們當時做了很多預熱,數據的預熱,應用的預熱,連接的預熱。

  • 數據的預熱

先講數據的預熱,我們訪問一個數據,它的數據鏈路太長了,其實離應用越近可能效果越好。首先數據預測要看什麼數據該怎麼預熱?首先把量特別大的數據,跟用戶相關的數據,就是購物車、紅包、卡券,做數據庫的預熱。

  • 模擬用戶查詢,查詢這個數據庫,把它的數據放到我們的內存裏面。
  • 很多應用都是靠緩存擋住的,緩存一旦失效數據庫就掛掉,因爲數據庫擋不住。這時要提前把數據預熱到緩存裏面。

做數據的預熱的目的是爲了減少關鍵的數據的鏈路,可以從內存讀到的就沒必要去緩存中讀,可以從緩存中讀的就不應該訪問數據庫。

  • 應用的預熱

1、小流量服務預熱

相比於一般場景下,剛發佈微服務應用實例跟其他正常實例一樣一起平攤線上總 QPS。小流量預熱方法通過在服務消費端根據各個服務提供者實例的啓動時間計算權重,結合負載均衡算法控制剛啓動應用流量隨啓動時間逐漸遞增到正常水平的這樣一個過程幫助剛啓動運行進行預熱,詳細 QPS 隨時間變化曲線如圖所示:

9.png

應用小流量預熱過程QPS曲線

同時我們可以通過調整小流量預熱的曲線,解決大促時擴容的機器流量平滑無損。

10.png

應用小流量預熱過程原理圖

通過小流量預熱方法,可以有效解決,高併發大流量下,資源初始化慢所導致的大量請求響應慢、請求阻塞,資源耗盡導致的剛啓動 Pod 宕機事故。值得一提的是 MSE 雲原生網關也支持了小流量預熱,我們看一下實戰中的效果,68 節點是剛擴容的實例。

11.png

2、並行類加載

JDK7 上,如果調用 Classloader.registerAsParallelCapable 方法,則會開啓並行類加載功能,把鎖的級別從 ClassLoader 對象本身,降低爲要加載的類名這個級別。換句話說只要多線程加載的不是同一個類的話,loadClass 方法都不會鎖住。

我們可以看 Classloader.registerAsParallelCapable 方法的介紹

protected static boolean registerAsParallelCapable()Registers the caller as parallel capable.The registration succeeds if and only if all of the following conditions are met:1. no instance of the caller has been created2. all of the super classes (except class Object) of the caller are registered as parallel capable

它要求註冊該方法時,其註冊的類加載器無實例並且該類加載器的繼承鏈路上所有類加載器都調用過 registerAsParallelCapable,對於低版本的 Tomcat/Jetty webAppClassLoader 以及 fastjson 的 ASMClassLoader 都未開啓類加載,如果應用裏面有多個線程在同時調用 loadClass 方法進行類加載的話,那麼鎖的競爭將會非常激烈。

MSE Agent 通過無侵入方式在類加載器被加載前開啓其並行類加載的能力,無需用戶升級 Tomcat/Jetty,同時支持通過配置動態開啓類加載並行類加載能力。

參考材料:http://140.205.61.252/2016/01/29/3721/

  • 連接的預熱

以 JedisPool 預建連接爲例,提前建立 Redis 等連接池連接,而不是等流量進來後開始建立連接導致大量業務線程等待連接建立。

org.apache.commons.pool2.impl.GenericObjectPool#startEvictor
protected synchronized void startEvictor(long delay) {
    if(null != _evictor) {
        EvictionTimer.cancel(_evictor);
        _evictor = null;
    }
    if(delay > 0) {
        _evictor = new Evictor();
        EvictionTimer.schedule(_evictor, delay, delay);
    }
}

JedisPool 通過定時任務去異步保證最小連接數的建立,但這會導致應用啓動時,Redis 連接並未建立完成。

主動預建連接方式:在使用連接之前使用 GenericObjectPool#preparePool 方法去手動去準備連接。

在微服務上線過程中,在初始化 Redis 的過程中提前去創建 min-idle 個 redis 連接,確保連接建立完成後再開始發佈服務。

JedisPool warm-internal-pool 同樣有類似問題,預建數據庫連接等異步建連邏輯,保證在業務流量進來之前,異步連接資源一切就緒。

  • 再談預熱

預熱爲什麼要做。我們阿里雲甚至有體系化的產品功能比如:無損上線,流量防護的預熱模式等,因爲預熱是保障系統在大促態穩定性的很重要的一環。通過預熱幫助我們的系統進入大促態,這個過程就好比於百米短跑。其他業務按照自然流來的都是長跑,但是短跑你必須得熱身,沒有熱身,起步階段可能就出抽筋、拉傷等大問題。

流控限流

流控是保障微服務穩定性最常用也是最直接的一種控制手段。每個系統、服務都有其能承載的容量上限,流控的思路非常簡單,當某個接口的請求 QPS 超出一定的上限後,拒絕多餘的請求,防止系統被突發的流量打垮。市面上最常見的方案是單機維度的流控,比如通過 PTS 性能測試預估某個接口的容量上限是 100 QPS,服務有 10 個實例,則配置單機流控 10 QPS。但很多時候,由於流量分佈的不確定性,單機維度的流量控制存在一些效果不佳的情況。

典型場景 1:精確控制對下游的調用總量

12.png

場景:服務 A 需要頻繁調用服務 B 的查詢接口,但服務 A 和 B 的容量存在差異,服務 B 約定最多給服務 A 提供總共 600 QPS 的查詢能力,通過流控等手段進行控制。

痛點:若按照單機流控的策略配置,由於調用邏輯、負載均衡策略等原因,A調用B到達每個實例的流量分佈可能非常不均,部分流量較大的服務 B 實例觸發單機流控,但總體限制量尚未達到,導致 SLA 未達標。這種不均的情況經常會發生在調用某個依賴服務或組件(如數據庫訪問)的時候,這也是集羣流控的一個典型場景:精確控制微服務集羣對下游服務(或數據庫、緩存)的調用總量。

典型場景 2:業務鏈路入口進行請求總量控制

13.png

場景:在 Nginx/Ingress 網關、API Gateway (Spring Cloud Gateway, Zuul) 進行入口流量控制,希望精確控制某個或某組 API 的流量來起到提前保護作用,多餘流量不會打到後端系統。

痛點:如果按照單機維度配置,一方面不好感知網關機器數變化,另一方面網關流量不均可能導致限流效果不佳;而且從網關入口角度來講,配置總體閾值是最自然的手段。

  • MSE 服務治理集羣流控

MSE 服務治理流控降級提供了以下特性:

1、專業的防護手段:

  • 入口流量控制:按照服務容量進行流量控制,常用於應用入口,例如:Gateway、前端應用、服務提供方等。
  • 熱點隔離:將熱點和普通流量隔離出來,避免無效熱點搶佔正常流量的容量。
  • 對依賴方隔離 / 降級:對應用和應用之間、應用內部採用隔離 / 降級手段,將不穩定的依賴的對應用的影響減至最小,從而保證應用的穩定性。
  • 系統防護:MSE 應用流控降級可以根據系統的能力(例如 Load、CPU 使用率等)來動態調節入口的流量,保證系統穩定性。

2、豐富的流量監控:

  • 秒級流量分析功能,動態規則實時推送。
  • 流量大盤編排,核心業務場景瞭然於胸。

3、靈活的接入方式:

提供 SDK、Java Agent 以及容器接入等多種方式,低侵入快速上線。

MSE 服務治理的集羣流控可以精確地控制某個服務接口在整個集羣的實時調用總量,可以解決單機流控因流量不均勻、機器數頻繁變動、均攤閾值太小導致限流效果不佳的問題,結合單機流控兜底,更好地發揮流量防護的效果。

對於上面的場景,通過 MSE 服務治理的集羣流控,無論是 Dubbo 服務調用、Web API 訪問,還是自定義的業務邏輯,均支持精確控制調用總量,而無關調用邏輯、流量分佈情況、實例分佈。既可以支撐數十萬 QPS 大流量控制,也支持分鐘小時級業務維度小流量精確控制。防護觸發後的行爲可由用戶自定義(如返回自定義的內容、對象)。

14.png

  • 防止突發流量將業務打垮

通過開啓 MSE 流量防護能力,根據壓測結果中不同接口和系統指標配置限流、隔離以及系統保護等規則,在最短的時間內接入並提供持續提供防護。碰到一些特殊的業務場景比預期的流量要大的多的時候,通過提前配置流控規則,及時地將多餘的流量拒絕或排隊等待,從而保護了前端系統不被打掛。同時,在一些核心接口也出現了突發的響應時間增大的情況,下游服務掛掉導致從網關到後端服務整條鏈路 RT 飆高,這時候利用 MSE 實時監控和鏈路功能快速定位到慢調用和不穩定服務,及時進行流控和併發控制,將系統從崩潰的邊緣拉了回來,業務迅速回到正常水平。這個過程就像“給系統做心臟復甦”,可以有效保障業務系統不掛掉,非常形象。

  • 防止熱點流量將業務打垮

15.png

大促中我們還要防止熱點流量,一些“黑馬”熱點商品,或者一些黑產刷單流量超出業務預期的流量進入我們的系統後,很可能會將我們的系統拖垮,我們通過熱點參數流控能力,可以將熱點用戶、熱點商品的流量控制在我們業務模型預估的範圍內,從而保護正常用戶的流量,有效保護我們的系統穩定性。

  • 保障調用端穩定性,避免級聯故障

16.png

我們都知道當流量近似穩態時,併發線程數 = QPS * RT(s) ,當我們調用的下游 RT 升高時,那麼併發的線程數將會飆高,從而出現服務調用的堆積。這也是大促中常見的一個問題,因爲依賴的下游支付服務因網絡抖動出現大量慢調用,導致該應用的線程池全部被該服務調用佔滿,無法處理正常業務流程。MSE 實時監控和鏈路功能可以幫助我們快速定位到慢調用和不穩定服務,準確找到應用變慢的根因,並對其配置併發隔離策略,可以有效保證我們應用的穩定性。

  • 保護重點業務,避免雪崩

17.png

雪崩是很可怕的一件事情,當它發生時,我們連救都救不回來了,只能眼睜睜地看着應用一個個宕機。因此在業務高峯期,某些下游的服務提供者遇到性能瓶頸,甚至影響業務。我們可以對部分非關鍵服務消費者配置自動熔斷,當一段時間內的慢調用比例或錯誤比例達到一定條件時自動觸發熔斷,後續一段時間服務調用直接返回 Mock 的結果,這樣既可以保障調用端不被不穩定服務拖垮,又可以給不穩定下游服務一些“喘息”的時間,同時可以保障整個業務鏈路的正常運轉。

大促的總結

18.png

每一次大促都是一次很寶貴的經驗,在大促後,做好總結和覆盤沉澱經驗是必不可少的一環。我們需要收集整理系統的峯值指標,系統的瓶頸與短板,以及踩過的坑,思考哪些東西是可以沉澱下來幫助下一次大促備戰,讓下一次大促無需重頭再來,讓下一次大促的用戶體驗可以更加絲滑。

大促還有許許多多的不確定性,大促流量和用戶行爲是不確定的,如何將不確定性風險變成相對確定的事情?大促是一個項目,備戰的方法論是把大促不確定性變成確定性,通過方法論推動產品最佳實踐配合大促成功,同時也通過大促這場考試,錘鍊我們的系統,沉澱我們的最佳實踐。在這裏祝大家 618 大促考試順利,系統穩如磐石。爲了用不停機的計算服務,爲了永遠在線的應用業務,Fighting!

MSE 註冊配置中心專業版首購享 9 折優惠,MSE 雲原生網關預付費全規格享 9 折優惠。

點擊此處,立刻享受優惠!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章