1. 程式人生 > >阿里巴巴的全鏈路壓測

阿里巴巴的全鏈路壓測

雙十一從 2009 誕生到現在,2013 年絕對是一個分水嶺。

為什麼這麼說?因為 2013 有了全鏈路壓測。

每年的 11 月 11 日 00:00:00,阿里巴巴集團最緊張激動的時刻到來了。多收檔的熱情這一刻開始爆發,反映到數字上是去年雙十一今人的記錄:24 小時交易額 1012 億,交易建立峰值 17.2w;而在二進位制世界裡面,則是極短時間內如海嘯般湧入的超大規模流量。

流量洪峰的殺傷力,曾在 2011 年和 2012 年給技術團隊留下了午夜驚魂的難忘回憶。然而隨著全鏈路壓測的登場,它改變了阿里巴巴對應流量洪峰的態度和方式,也一次次重新整理中國網際網路世界的紀錄。

為什麼需要容量規劃?

阿里巴巴有著非常豐富的業務形態,每種業務都由一系列不同的業務系統來提供服務,每個業務系統都分散式地部署在不同的機器上。隨著業務的發展,特別是在大促營銷等活動場景下(比如雙 11),需要為每個業務系統準備多少機器對於阿里巴巴技術團隊來說是一大難題。“容量規劃”正是為解決這個難題而誕生,容量規劃的目的在於讓每一個業務系統能夠清晰地知道:什麼時候應該加機器、什麼時候應該減機器?雙 11 等大促場景需要準備多少機器,既能保障系統穩定性、又能節約成本?

阿里高可用的兩大法寶

容量規劃四步走

在雙 11 等大促場景的準備過程當中,容量規劃一般分為四個階段:

  1. 業務流量預估階段:通過歷史資料分析未來某一個時間點業務的訪問量會有多大;

  2. 系統容量評估階段:初步計算每一個系統需要分配多少機器;

  3. 容量的精調階段:通過全鏈路壓測來模擬大促時刻的使用者行為,在驗證站點能力的同時對整個站點的容量水位進行精細調整;

  4. 流量控制階段:對系統配置限流閾值等系統保護措施,防止實際的業務流量超過預估業務流量的情況下,系統無法提供正常服務。

在第一個階段當中,通過合適的預測演算法和豐富的歷史資料,通常能夠比較準確地預估業務的訪問量。即使在第一階段預估的業務訪問量跟實際的存在誤差,通過第四階段的流量控制也能夠確保站點始終處於良好的服務狀態。做完業務訪問量的預估之後,容量規劃進入第二階段,為系統進行容量的初步評估。如何通過精準的容量評估,用最小的成本來支撐好預估的業務量是這個階段的核心問題。

要計算一個系統需要多少臺機器,除了需要知道未來的業務呼叫量之外,還有一個更重要的變數,就是單臺機器的服務能力。獲取單臺機器的服務能力在阿里巴巴是通過單機壓測的方式來獲取。在阿里巴巴,為了精準地獲取到單臺機器的服務能力,壓力測試都是直接在生產環境進行,這有兩個非常重要的原因:單機壓測既需要保證環境的真實性,又要保證流量的真實性。否則獲取到的單臺機器服務能力值將會有比較大的誤差,影響到整個容量規劃的準確性。

生產環境進行單臺機器壓力測試的方式主要分為 4 種:

阿里高可用的兩大法寶

模擬請求:通過對生產環境的一臺機器發起模擬請求呼叫來達到壓力測試的目的

模擬請求的實現比較簡單,也有非常多的開源或者商業工具可以來做請求模擬,比如 apache ab、webbench、httpload、jmeter、loadrunner。通場情況下,新系統上線或者訪問量不大的系統採用這種方式來進行單機壓測。模擬請求的缺點在於,模擬請求和真實業務請求之間存在的差異,會對壓力測試的結構造成影響。模擬請求的另一個缺點在於寫請求的處理比較麻煩,因為寫請求可能會對業務資料造成汙染,這個汙染要麼接受、要麼需要做特殊的處理(比如將壓測產生的資料進行隔離)。

複製請求:通過將一臺機器的請求複製多份傳送到指定的壓測機器

為了使得壓測的請求跟真實的業務請求更加接近,在壓測請求的來源方式上,我們嘗試從真實的業務流量進行錄製和回放,採用請求複製的方式來進行壓力測試。請求複製的方式比請求模擬請求方式的準確性更高,因為業務的請求更加真實了。從不足上來看,請求複製同樣也面臨著處理寫請求髒資料的問題,此外複製的請求必須要將響應攔截下來,所以被壓測的這臺機器需要單獨提供,且不能提供正常的服務。請求複製的壓力測試方式,主要用於系統呼叫量比較小的場景。

請求轉發:將分散式環境中多臺機器的請求轉發到一臺機器上

對於系統呼叫量比較大的場景,我們有更好的處理辦法。其中的一種做法我們稱為請求的引流轉發,阿里巴巴的系統基本上都是分散式的,通過將多臺機器的請求轉發到一臺機器上,讓一臺機器承受更大的流量,從而達到壓力測試的目的。請求的引流轉發方式不僅壓測結果非常精準、不會產生髒資料、而且操作起來也非常方便快捷,在阿里巴巴也是用的非常廣泛的一種單機壓測方式。當然,這種壓測方式也有一個前提條件就是系統的呼叫量需要足夠大,如果系統的呼叫量非常小,即使把所有的流量都引到一臺機器,還是無法壓測到瓶頸。

調整負載均衡:修改負載均衡裝置的權重,讓壓測的機器分配更多的請求

與請求引流轉發的方式類似,最後一種壓測方式同樣是讓分散式環境下的某一臺機器分配更多的請求。不同的地方在於採用的方式是通過去調整負載均衡裝置的權重。調整負載均衡方式活的的壓測結果非常準確、並且不會產生髒資料。前提條件也需要分散式系統的呼叫量足夠大。

在阿里巴巴,單機壓測有一個專門的壓測平臺。壓測平臺在前面介紹的 4 種壓測方式基礎上,構件了一套自動化的壓測系統。在這個系統上,可以配置定時任務定期對系統進行壓測,也可以在任意想壓測的時間點手動觸發一次壓測。在進行壓測的同時,實時探測壓測機器的系統負載,一旦系統負載達到預設的閾值即立刻停止壓測,同時輸出一份壓測報告。

因為是在生產環境進行壓測,我們必須非常小心,保障壓測過程不影響到正常的業務。在單機壓測平臺上,每個月將進行 5000 次以上的壓測,系統釋出或者大的變更都將通過單機壓測來驗證效能是否有變化,通過單機壓測獲取的單機服務能力值也是容量規劃一個非常重要的參考依據。

有了預估的業務訪問量,也知道了系統單臺機器的服務能力,粗略的要計算需要多少臺機器就非常簡單了。

最小機器數 = 預估的業務訪問量 / 單機能力。

通常情況下,我們會預留少量的 buffer 來防止評估的誤差和意外情況。

為什麼需要全鏈路壓測?

阿里高可用的兩大法寶

進行到這一步,我們已經完成了系統容量的粗略評估,然而做到這一步是不是就夠了呢?過去的教訓曾經狠狠地給我們上了一課。

我們對每一個系統都做好了粗略的容量計算,以為一切都會比較順利了,可是真實場景並非如此,當雙 11 的零點到來的時候,許多系統的執行情況比我們想象的要更壞。原因在於真實的業務場景下,每個系統的壓力都比較大,而系統之間是有相互依賴關係的,單機壓測沒有考慮到依賴環節壓力都比較大的情況,會引入一個不確定的誤差。這就好比,我們要生產一個儀表,每一個零件都經過了嚴密的測試,最終把零件組裝成一個儀表,儀表的工作狀態會是什麼樣的並不清楚。

事實上我們也有一些血的教訓。在 2012 年的雙 11 零點,我們一個系統的資料庫的網絡卡被打滿了,從而導致部分使用者無法正常購物,儘管當時我們做了非常充分的準備,但還有一些事情是我們沒考慮到的。

需要怎麼樣才能解決這個問題?在 2013 年的雙 11 備戰過程當中,在很長一段時間內這都是我們面臨的一個難題。在中國,學生通常都會有期末考試,為了在期末考試中取得比較好的成績,老師通常會讓學生們在考試前先做幾套模擬題。雙 11 對我們的系統來說就是一年一度的期末考試,所以我們冒出了這麼一個想法:“如果能讓雙 11 提前發生,讓系統提前經歷雙 11 的模擬考驗,這個問題就解決了”。通過對雙 11 零點的使用者行為進行一次高模擬的模擬,驗證整個站點的容量、效能和瓶頸點,同時驗證之前進行的容量評估是否合理,不合理的地方再進行適當的微調。

我們為此研發了一套新的壓測平臺——“全鏈路壓測”。雙 11 的模擬可不是一件簡單的事情,上億的使用者在阿里巴巴平臺上挑選、購買好幾百萬種不同型別的商品,場景的複雜性非常高。有三個最主要的難點需要解決:

  1. 用於的請求量非常大,在雙 11 零點,每秒的使用者請求數超過 1000w;

  2. 模擬的場景要跟雙 11 零點儘可能的貼近,如果模擬的場景跟雙 11 零點差距太大,將不具備實際的參考價值,而雙 11 零點的業務場景非常複雜;

  3. 我們需要在生產環節去模擬雙 11,如何去做到模擬的使用者請求不對正常的業務和資料造成影響。

為了能夠發出每秒 1000w 以上的使用者請求,全鏈路壓測構件了一套能夠發出超大規模使用者請求的流量平臺。流量平臺由一個控制節點和上千個 worker 節點組成,每一個 worker 節點上都部署了我們自己研發的壓測引擎。壓測引擎除了需要支援阿里巴巴業務的請求協議,還需要具備非常好的效能,要不然 1000w 的使用者請求,我們將無法提供足夠多的 worker 節點。上千個壓測引擎彼此配合、緊密合作,我們能像控制一臺機器一樣控制整個壓測叢集,隨心所欲的發出 100w/s 或者 1000w/s 的使用者請求。

阿里高可用的兩大法寶

1000w+/s 的使用者請求量不僅要能夠傳送出來,而且還需要跟雙 11 的使用者行為儘可能的接近,而雙 11 是一個非常複雜的業務場景。為了使得模擬能夠更加真實,我們做了非常多的工作。首先,我們從生產環境提取一份跟雙 11 同等數量級的基礎資料(包含:買家、賣家、店鋪、商品、優惠等等),做好篩選和敏感欄位的脫敏,作為全鏈路壓測的基礎資料。然後基於這些基礎資料,結合前幾年的歷史資料,通過相應的預測演算法,得到今年雙 11 的業務模型。

雙 11 的業務模型包含 100 多個業務因子,比如:買家數量、買家種類、賣家數量、賣家種類、商品數量、商品種類,pc 和無線的佔比,購物車裡的商品數量,每一種業務型別的訪問量級等等)。有了業務模型之後,再根據業務模型構造相應的壓測請求,最終將壓測請求上傳到壓測引擎。

全鏈路壓測直接在生產環境進行雙 11 的模擬,在前面的單機壓測方式中也有提到,對於模擬請求的方式,需要考慮髒資料的處理方式。全鏈路壓測的所有資料都在生產環境做了資料隔離,包含儲存、快取、訊息、日誌等一系列的狀態資料。在壓測請求上會打上特殊的標記,這個標記會隨著請求的依賴呼叫一直傳遞下去,任何需要對外寫資料的地方都會根據這個標記的判斷寫到隔離的區域,我們把這個區域叫做影子區域。全鏈路壓測對粗略的容量評估起到了精調的作用,使雙 11 零點的各種不確定性變的更加確定。

阿里高可用的兩大法寶

我們在 2013 年雙 11 前夕的全鏈路壓測過程當中共發現了 700 多個系統問題,2014、2015、2016 同樣也發現了好幾百個問題。這些問題如果沒有在全鏈路壓測的過程當中被發現,很有可能會在雙 11 零點的真實業務場景當中暴露出來,將造成嚴重的可用性影響。

超限後的流量控制如何做?

前面章節我們討論的都是”容量規劃”,我們知道容量規劃是基於一套精密的業務模型,而這個業務模型是根據歷年來的大促資料,以及複雜的預測模型推算出來的。然而,不論這個模型多麼強壯,它始終是一個預測。這就意味著我們存在著預測和現實流量有誤差。

這個並不僅僅是一個擔心,這個發生過非常多次。最近的一個例子是在 16 年的雙 11,我們為某一個重要的場景預備了足以應付 16.2 萬每秒的峰值,然而那天的峰值實際上到達了 20 萬每秒,超過我們準備能力將近 13%,你可能覺得這隻會對峰值產生影響,這些額外的 2W 請求馬上就會被消耗掉,但並不是你想的這樣。

當一臺機器超負荷運轉的時候,這臺處理請求的時間會變長。這會給使用者帶來不好的體驗,使用者會試圖重複提交請求,這無形中又給系統帶來了更多的請求壓力。隨著請求堆積的越來越多,系統性能會逐漸下降甚至無法響應新的請求。

當一臺機器掛掉以後, 負載均衡會把請求重定向到另外的機器上去,這又無形中給別的機器帶來了更多的任務,而這些機器也處於一個飽和的狀態,很快也會像第一臺機器一樣,也無法響應新的請求。就這樣,在很短的時間之內,越來越多的機器會停止響應,最終導致整個叢集都無法響應。這就使我們常常說的“雪崩效應”。一旦“雪崩”發生,就很難停止。我們必須有一個有效的機制,來監控和控制進入的流量,來防止災難的發生。

然而,流控並不僅僅用於流量高峰,它在很多的場景都可能用的到。比如在一個業務的鏈路上,有一個下游系統出現了問題,響應時間變得很長。這個問題在鏈路上會被放大,甚至導致整個鏈路不可用。這意味著流控也需要可以根據響應時間來控制系統的健康,當一個應用響應的時間超過閾值,我們可以認為這個應用不可控,應該迅速將它降級。

除了流控的激發原因之外,流控也可以靈活的定義流控的方式。不同的業務場景,可以採取不同的流控方式。比如說,對於有的應用,我們可以簡單的丟棄這個請求,有的應用,則需要對下游應用進行降級,甚至直接加入黑名單。而有的應用,則需要把這些多餘的請求排隊,等到高峰期過後,系統沒有那麼忙碌之後,再逐步消耗這些流量。

所以,我們最終的流控框架可以從三個緯度著手,執行狀況,呼叫關係,流控方式。應用可以靈活的根據自己的需求,任意組合。

阿里高可用的兩大法寶

下面這個是我們流控的架構圖:

阿里高可用的兩大法寶

  • 第一步,我們在程式入口給所有的方法都進行埋點;

  • 第二步,我們把這些埋點方法的執行狀態,呼叫關係統計記錄下來;

  • 第三步,我們通過從預設好的規則中心接收規則,來根據第二步中統計到的系統狀態進行控制。

然而,當系統發生流控的時候,系統雖然是安全的,但是它始在一個“受損”狀態下執行。所以我們也在問題排除之後,解除流量控制。用我們上面的場景作為例子。一個鏈路上的一個下游應用出現了問題,導致響應時間變長,從而導致上游應用的系統負載過高。過了一會兒之後,這個下游應用恢復了,響應時間大大縮短。然而這個時候,上游應用的負載並不能馬上恢復,因為進來的請求已經堆積了一段時間了。

這就意味著,如果我們採用傳統的方式,用系統負載來判斷是否應該恢復流控,那麼即使問題已經修復,系統地負載仍然處於一個比較高的狀態。這樣就會導致系統恢復慢。既要迅速恢復,同時也要系統穩定。最後我們採取的方式是,讓 rt,load, 允許通過的 qps 達到動態平衡。

阿里高可用的兩大法寶

讓我們來看一下最後取得的效果。用了新的演算法之後,我們可以看到系統穩定在一定的範圍之內,同時當問題機器恢復之後,流量也能夠很快的恢復。

阿里高可用的兩大法寶

從近幾年雙 11 零點的業務穩定性上來看,全鏈路壓測是一個明顯的分水嶺,在全鏈路壓測之後整個站點的穩定性明顯好於全鏈路壓測之前。全鏈路壓測已經成為阿里巴巴大促備戰的必要環節,無論是雙 11 大促、雙 12 大促,還是平時一些比較小的促銷活動,每一次活動之前都會進行好幾輪的全鏈路壓測來對系統進行一次全方位的模擬驗證,提前暴露各個環節的問題。全鏈路壓測的誕生使得阿里大促備戰的系統穩定性有了質的提升,被譽為大促備戰的核武器。

除了全鏈路壓測來驗證我們的容量規劃的正確性以外,流量控制的策略在我們的大促技術規劃時也很重要,限流框架通過 自由組合執行狀態,呼叫鏈路,限流措施的靈活組合,覆蓋了多種業務場景。同時,通過動態平衡,可以做到快恢復,最低的減低對使用者使用體驗的衝擊。流量控制和流量壓測兩者結合,讓我們的系統穩定健康地渡過各種極限業務場景。

寫在最後

阿里研究員蔣江偉曾經說過,“今天如果有人問我怎麼做雙十一,怎麼做大促活動,我會告訴他一個非常簡單的方法,就是做好容量規劃,做好限流降級。”現在,基於阿里在雙 11 大促上的多年的系統高可用保障經驗,全鏈路壓測服務 6 月份即將在阿里雲上線(在原有云產品 PTS 的基礎上進行全方位升級),大家都可以近距離的使用阿里的這套核武器了。

 

 

參考:https://my.oschina.net/cctester/blog/994727