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

阿里巴巴雲原生發表於2022-06-09

作者:泮聖偉(十眠)

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

點選下方連結,立即檢視視訊講解!

https://yqh.aliyun.com/live/d...

大促的不確定性挑戰

 title=

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

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

目標確定

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

 title=

備戰流程

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

容量評估

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

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

 title=

  • 效能評估

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

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

優勢一:功能強大

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

**優勢二:流量真實

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

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

  • 業務以及系統的變化

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

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

 title=

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

 title=

 title=

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

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

 title=

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

  • MSE 閘道器 容量參考

 title=

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

預案

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

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

預熱

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

  • 資料的預熱

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

  • 模擬使用者查詢,查詢這個資料庫,把它的資料放到我們的記憶體裡面。
  • 很多應用都是靠快取擋住的,快取一旦失效資料庫就掛掉,因為資料庫擋不住。這時要提前把資料預熱到快取裡面。

做資料的預熱的目的是為了減少關鍵的資料的鏈路,可以從記憶體讀到的就沒必要去快取中讀,可以從快取中讀的就不應該訪問資料庫。

  • 應用的預熱

1、小流量服務預熱

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

 title=

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

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

 title=

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

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

 title=

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...

  • 連線的預熱

以 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:精確控制對下游的呼叫總量

 title=

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

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

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

 title=

場景:在 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 大流量控制,也支援分鐘小時級業務維度小流量精確控制。防護觸發後的行為可由使用者自定義(如返回自定義的內容、物件)。

 title=

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

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

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

 title=

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

  • 保障呼叫端穩定性,避免級聯故障

 title=

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

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

 title=

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

大促的總結

 title=

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

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

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

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

相關文章