分佈式系統測試在阿里雲的實踐

轉載自http://www.infoq.com/cn/articles/distributed-systems-test

1. 阿里雲的分佈式系統

飛天是阿里雲獨立開發的大規模分佈式計算與存儲系統,兼有分佈式存儲和分佈式計算的多重功能。基於飛天大規模分佈式系統,我們開發了彈性計算,海量郵箱服務,Key-Value存儲引擎,結構化數據存儲引擎和海量數據處理服務等一系列的上層服務,並且基於這些上層服務,我們運營了了Open Table Service和Open Storage Service等多項開放服務。

2. 測試的層次結構

按照層次和功能,測試可以分爲單元測試,功能測試,系統測試,集成測試,端到端測試等若干種測試。這裏首先要提的是單元測試,單元測試更像是一種預防代碼錯誤的手段,而不是檢測代碼錯誤的手段,我們用覆蓋率(包括行覆蓋和分支覆蓋)來檢驗單元測試的質量。當然我們也都知道這些指標不能作爲單元測試好壞的標準,所以,在項目中,我們也非常注重代碼審查,其中包括了單元測試代碼的審查。

傳統的一般來說,一個產品一般只有對外接口進行功能測試和系統測試,但是由於飛天的代碼非常的複雜,模塊非常多,每個模塊都具有了一個產品的複雜度。所以,我們在模塊層面也會進行功能測試和系統測試,爲的是保證系統質量能夠得到迴歸,在有代碼修改的時候,影響上層業務使用的接口或者隱含邏輯一旦發生變化,能夠第一時間知曉。功能測試非常注重對接口函數的覆蓋,並且會對各種參數的邊界進行復雜的探測,而系統測試比較注重穩定性,一致性,性能甚至容災能力等各個方面。

在飛天系統內部,有專門的集成測試部門,集成測試團隊有一個非常大的責任是通過迴歸測試用例來保證系統中的各個模塊,在版本發佈時在一起能夠很好的工作,並對之前每個模塊定下的質量驗收標準進行驗證。一旦發現重大風險,集成測試部門有權力不發佈其中某些Feature,如果這個Feature有某種重要的商業用途,則進行推遲整體版本的發佈。這一點可能和傳統軟件不太一樣。當分佈式軟件已經比較成熟的時候,底層很多模塊的Feature在某個版本的刪減,大多數時候不會影響到用戶的正常使用,但是如果由於這個Feature的發佈導致分佈式系統出現不穩定或者性能大幅下降,則得不償失。

端到端測試在內部有個簡潔的名字叫做E2E Testing。E2E Testing的責任人需要負責向上層使用這個模塊或者系統的用戶方瞭解具體的需求,這個需求不僅是一個對接口功能的需求,還包含了數據量的需求,機器規模的需求,吞吐率的需求,延遲時間的需求以及業務量在一天或者一週內的曲線等等信息,然後設計E2E的測試程序,能夠儘可能的模擬真實的數據情況。在本身上層業務就已經有數據的情況下,還可以通過導入真實業務的數據進行測試。通過長時間的E2E測試,驗證各種指標。

一般來說,我們只有在通過了最後的E2E測試之後才能發佈版本,上線讓應用使用我們的分佈式系統。

3. 注重探索式測試

分佈式系統的測試非常的複雜,你既無法通過窮舉來羅列所有的情況,也不能簡單的對接口和性能進行迴歸來證明一個版本的合格。因爲對於分佈式系統,不同的數據量,不同的壓力,不同的機器規模,有可能在代碼裏面走的路徑完全不一樣。而且,由於在大的壓力下,磁盤,內存和網絡有可能成爲系統的瓶頸。更有甚者,在壓力不均勻的情況下,單臺機器可能會成爲整個系統的瓶頸。所以,我們是沒有辦法設計這麼多的測試用例來分別覆蓋所有的這些分支情況的。

我們有詳細的監控系統可以監控整個集羣的各種參數,這些參數不光是硬件參數,更多的是軟件本身通過調用我們監控系統的API來完成對自身某些指標的統計。這些統計不光在線上系統能夠起到監控的作用,執行測試的人員可以通過不斷改變測試的各項參數,結合這些指標的變化進行探索式的測試。通常,通過指標在某些壓力變化下或者隨着時間推移時的異常行爲,測試人員會更容易找到一些深藏的Bug。另外,在系統級測試時,通過對系統內部Error Log的監控也能達到很好的效果。

4. 灰盒測試是分佈式測試的最有效方法

上面講到了探索式的測試十分重要,但是光有探索,如果測試人員本身不瞭解系統的一些內部邏輯,會出現兩種情況:第一種是,只驗證設計好的場景,其他一些異常的情況,自己無法解釋,但是本身又不是驗證標準,導致很多隱藏的問題最終在線上爆發;第二種是,一個沒頭的蒼蠅,漫無目的的進行探索,最終浪費了時間,卻達不到好的效果。在飛天分佈式系統測試中,我們要求測試人員必須從方案設計之初甚至是討論需求的時候就和開發的同學在一起討論,測試的同學需要比開發更加理解系統的設計原則。

有一個很典型的例子是,早期,我們內部開發一個基於表結構的存儲引擎時,曾經出現過這樣一件事情:測試程序在最終驗證一致性時,一直都是通過的,但是業務方和我們一起做E2E測試的時候,會有很低的概率發現數據讀出來是錯誤的。測試人員百思不得其解,最後發現,這份數據在寫入的時候,會先在三個地方進行修改,但是由於一些時序和鎖的問題,在改過了兩個地方之後就返回成功了,第三個地方是在內存中,過一陣子就會被重新刷成正確的值。如果當時測試的同學知道系統裏面這些設計,當時就會設計寫入過程中,對數據一致性的檢測,不會在用戶場景中再發現問題,解決的效率也會因此而提高。

5. 帶壓力和隨機故障模擬的長時間穩定性測試

分佈式系統往往是在多臺機器上運行多個進程,每個進程都是一個獨立主體,運行着自己獨立的邏輯,各個進程都有可能因爲軟硬件故障導致邏輯執行異常。分佈式系統要保證的是任何局部的進程異常都不會影響系統的可用性,因此必須要做必要故障模擬和恢復測試。由於進程之間通訊協議的複雜,故障類型的多樣,並不能夠模擬所有可能出現故障和進程狀態的組合,也就是說這樣的組合是爆炸的。

在飛天實際的測試過程中,我們採用的是帶背景壓力和隨機故障模擬的長時間穩定性測試。這也是飛天主版本發佈的最後一道關。背景壓力主要是各個主要模塊的讀寫壓力,還有一些諸如CPU,Memory,Network的資源消耗器,以模擬機器資源緊張場景。故障模擬操作又比如磁盤錯誤,包括壞盤,只讀等,機器宕機,重啓,斷網,主要模塊進程重啓,假死等,這些操作都會按照預先設定比例進行隨機組合;在這樣的背景壓力和故障操作下,長時間(至少7x24 小時)持續運行上層應用模擬程序/作業。同時通過在線監控工具來檢查系統是否正常。飛天很多重要的bug都是通過這個測試被發現的。當然這類測試也有短處,就是問題調查需要較長的時間,要求測試人員對系統有較深的瞭解和診斷能力。

6. 如何保障測試的質量

單元測試雖然可以用Coverage工具來檢驗行覆蓋和分支覆蓋,但是功能測試和系統測試在運行時,進程運行在上百上千臺機器上,很難通過既有的軟件來蒐集到coverage數據。我們內部開發了一個叫做Log Coverage的工具,能夠通過程序在運行過程中輸出的Log信息的多少來判斷測試是否有足夠的覆蓋率。通過拿到生產線上的Log與測試中的Log進行比較,會找到我們之前沒有測試到的地方。另外,通過對程序中從來沒有打印出的Error Log的檢查,我們也可以知道有多少異常邏輯我們沒有測試過。


感謝賈國清對本文的審校。

給InfoQ中文站投稿或者參與內容翻譯工作,請郵件至[email protected]。也歡迎大家通過新浪微博(@InfoQ)或者騰訊微博(@InfoQ)關注我們,並與我們的編輯和其他讀者朋友交流。

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