1. 程式人生 > 實用技巧 >12丨效能場景:做引數化之前,我們需要考慮什麼

12丨效能場景:做引數化之前,我們需要考慮什麼

在效能測試中,我們要關注的資料主要有以下幾類,分別是引數化資料、監控資料和基礎鋪底資料。

我們今天先描述第一種引數化資料,在後面的文章中再描述其他資料。

首先我們需要了解,為什麼要關注效能場景中的引數化資料呢?我以下面的兩個例子說明一下。

在我的工作經歷中,見過很多初級效能測試工程師不知道如何設定合理的引數化資料,以至於資料會出現這兩種情況。

1.資料不均衡

有些人直接用同一個資料執行混合場景測試,在這種情況下對伺服器的壓力和真實環境下的完全不一樣。有時我們不得不造很多引數化資料,也有很多工程師不考慮資料庫表中的資料直方圖,就直接在少量的引數化資料中建立了大量的相關記錄。比如說,在電商系統中造出大量的購買記錄;在銀行系統中造出大量的個人流水記錄。

這些都不能滿足真實使用者場景的需要,導致的結果就是整個測試結果都毫無意義。

2.引數化資料量不足

有時候,如果我們選擇用非常少量的資料執行大量業務操作的場景,就會導致壓力和真實生產環境完全不一致。比如說,用100個數據執行出上萬甚至上億的業務操作。

那麼到底該怎樣才能合理地設定引數化資料呢?

引數化資料的疑問

根據我的經驗,在引數化測試資料的獲取和考慮上,我們一般會有以下四個常見的疑問。

  1. 引數化資料應該用多少資料量?
  2. 引數化資料從哪裡來?
  3. 引數多與少的選擇對系統壓力有什麼影響?
  4. 引數化資料在資料庫中的直方圖是否均衡?

接下來,我們對這些問題一一做出解答。

引數化資料應該用多少資料量?

首先,引數化資料要用到多少取決於場景,舉例來說,對一個壓力工具執行緒數為100,TPS有1000的系統,如果要執行30分鐘,則應該取得的引數化資料是下面這樣的。

資料型別、限制條件和資料量計算的方式如下表所示:


從技術角度看,根據資料型別就可以確定應該用多少條引數化資料了。但是這樣考慮就夠了嗎?當然是不夠的。因為除了技術的限制之外,還有業務場景的需求。

根據業務場景計算引數化資料量

在效能場景中,我們需要根據實際的業務場景來分析需要用到什麼樣的資料,以便計算資料量。這裡的資料型別包括可迴圈使用的資料和不可迴圈使用的資料。使用者登入是一個在各行業中幾乎都會遇到的事務,我們拿它來舉例說明,下面這張圖是一個使用者登入的介面。

這裡需要用到兩種資料,一個是帳號,一個是密碼。帳號和密碼一定是可以真實登入到系統的,不然無法完成後續的業務。很顯然對於登入來說,不同的人一定是用不同的使用者登入的。

場景一

首先我們來看下場景一。有時候我們做指令碼時考慮的是,有多少執行緒(Thread)就配置多少使用者,讓每個執行緒在同一個使用者上迴圈執行。

如下圖所示:

需要注意的是,在本文中,每一個“—user1→”代表一次指令碼完全的迭代。

這樣的使用者引數化配置,只能滿足一些比較特定的場景。比如說,使用者在早上登入系統之後,一直在系統中帶著登入session做業務操作,並且不會退出,只有在下班時才退出系統。

當我們要模擬一天中的業務峰值時,可以像上面這樣配置。登入一次,迴圈使用同一使用者的Session資訊。這就是前面提到的部分可迴圈資料。

在這樣的場景中,有多少執行緒就需要準備多少使用者資料。即:

Java
使用者資料=執行緒個數

場景二

但在有些場景中,這是完全錯誤的配置方式。比如說電商系統,用同一個使用者賬號不停迴圈購買商品,就是不符合真實場景的。

這時侯怎麼辦?我們可以用在壓力測試工具中模擬出來的執行緒的每一次迭代來代表一個使用者,如下所示:

這就是不可迴圈使用的資料。在這樣的場景中,就需要考慮場景的TPS和持續時間了。使用者資料的計算方法是:

Java
tpsx持續時間(秒級)

我們舉個例子,假如有一個100TPS的場景,持續30分鐘。那麼計算方式如下:

Java
100x30*60=180000(條使用者資料)

這裡再多說一句,壓力工具的執行緒數量也並不是常說的併發數的概念。這個我們在前面已經說得很清楚了。

場景三

但是還有一種情況,就是在一個執行緒之中,可以迴圈使用固定條目的資料。如下所示:

在這種情況下,我們就需要根據實際的業務場景判斷了。在同樣的100TPS場景中,如果準備了1000條資料,就可以讓每個執行緒用10個不同的資料。

這樣的場景沒有固定的條數限制,只能根據實際的業務判斷。

所以在配置引數之前,我們需要先判斷這個引數是什麼型別的資料。

如果是可迴圈使用的資料,那麼它在真實的效能場景中非常少,也就是說只使用一條或幾條測試資料的真實業務場景是非常少的。

引數化資料從哪裡來?

計算了引數化資料量之後,還有一個重要的問題需要解決,就是引數化資料從哪裡來呢?這一步的目的是要確保引數的有效性。

引數化資料從大體上劃分,主要有兩個來源。

第一類

使用者輸入的資料在後臺數據庫中已存在,比如我們上面示例中的使用者資料。這類資料的特點是什麼呢?

  1. 存在後臺數據庫中;
  2. 需要使用者主動輸入;
  3. 使用者輸入的資料會和後臺資料庫中的資料做比對。

這類資料必須查詢資料庫之後再引數化到工具中。

第二類

使用者輸入的資料在後臺數據庫中不存在。在業務流中,這些資料會Insert或Update到資料庫中。這類資料的特點是什麼呢?

  1. 資料庫中原本不存在這些資料;
  2. 在指令碼執行成功後會將這些資料insert或update到資料庫中;
  3. 每個使用者輸入的資料可能相同,也可能不同,這取決於業務特點。

這類資料必須通過壓力工具做引數化,同時也必須滿足業務規則。

我同樣用前面的使用者引數為例,由於使用者登入的時候一定要和資料庫中的使用者資料做比對,只有使用者名稱密碼都完全正確的情況下才可以成功登入,所以這樣的使用者引數一定要從後臺資料庫中查詢得到。

在本例中,通過後臺數據庫使用者表的查詢真實可用的使用者數共有10萬。

如果在業務場景中,是不可迴圈使用的使用者資料,那麼很顯然,在可以支援100TPS併發的系統中,這些使用者數量只夠使用16.67分鐘。

Java
100000/100/60=16.67(分鐘)

總之,引數化時需要確保資料來源以保證資料的有效性,千萬不能隨便造資料。這類資料應該滿足兩個條件:

  1. 要滿足生產環境中資料的分佈;
  2. 要滿足效能場景中資料量的要求。

引數取多與少對系統壓力有什麼影響?

根據上文中的第二個條件,這裡就要說一下資料量的要求了。

從經驗上判斷,對一個系統來說,獲取的引數化資料是否合理,會直接影響壓力測試的結果有沒有意義。

我們根據下面這張圖來理解一下資料在系統中的流轉。

這張圖中,綠色部分代表資料在各系統中的正常大小,而黑色部分代表壓力工具中使用的資料量大小。如果壓力工具使用的資料量少,那麼應用伺服器、快取伺服器、資料庫伺服器,都將使用少量的快取來處理。

顯然圖中所示的黑色部分是很少的,完全不能把後端各類伺服器的快取佔用到真實場景中應該有的大小,所以在這種狀態之下是測試不出來真實場景下的壓力的。

對資料庫連線的儲存裝置來說同樣也有影響。如果資料量少,則相應的儲存的I/O使用就少。對於一個沒有被Cache的資料來說,首次使用肯定會觸發I/O,也就是會產生定址、PageFalut等情況。

引數取得過多,對系統的壓力就會大;引數取得過少,不符合真實場景中的資料量,則無法測試出系統真實的壓力。

引數化資料在資料庫中的直方圖是否均衡?

對於引數化資料來說,如果資料取自於資料圖,我們通常要檢查一下資料庫中的資料直方圖。 對於直接從生產上拿的資料來說,資料的分佈更為精準。但是對於一些在測試環境中造的資料,則一定要在造資料之後,檢查下資料分佈是否與生產一致。

我們以一個案例開始。

在效能場景執行過程中,有一個業務的TPS如下圖所示:

很明顯,圖中TPS中間掉下來的情況是非常不合理的。

為什麼會導致這個情況呢?在這個示例中,這種現象是由抽取的資料量不合理導致的,我們來看一下資料分佈。

客戶iD,客戶流水記錄數
'客戶ID1', '69865'
'客戶ID2', '55075'
......
'客戶ID5374728, '177'
'客戶ID5374729', '176'
'客戶ID5374730', '175'

顯然通過統計之後,我們可以發現客戶的流水記錄數是完全不均衡的,而這個業務指令碼是會返回客戶的流水記錄的。當用到記錄數多的客戶ID時,就會導致TPS嚴重下降,這是因為這些資料都要從儲存裝置中獲取,一旦資料量多,就會導致一系列的資源開銷;而用到記錄數少的客戶ID時,TPS就很高。

那麼針對這種情況,我們該怎麼處理呢?

首先分析業務邏輯,確認客戶流水是否應該這麼多。在這個場景中,我們分析過業務,客戶的流水通常情況下都會在100~200之間,這是合理的情況,而上萬的資料量就是完全不合理的。

然後我們過濾掉不合理的資料即可。

這樣得到的引數化資料就符合真實場景了。