一、需求
在壓測的過程中,為了能夠壓測整個鏈路,通常需要多個接口進行並發, 每個接口的請求比例不盡相同。
比如此時此刻,我在寫博客,很多人在瀏覽博客,或者點贊、評論博客等等等,這些行為占比是不同的。
那么,我們怎么才能盡可能的模擬線上真實場景,對每個接口按照比例並發呢?
實現方法如下:
二、實現方法
設定一個用作講解的並發場景:
比如,同一時刻,點贊博客的請求占比10%,查看博客的請求占比90%,比例是1:9。
1、對每個請求設置循環次數。
如上場景,我們可以為查看博客的請求設置循環次數為9。
右擊【查看】請求→【插入上級】→【邏輯控制器】→【循環控制器】→【循環次數】設置為9→【運行】→【查看結果樹】
在請求的名稱后面加上這個參數,就可以看到請請求的順序:${__counter(true,i)}
${__threadNum}:統計線程數
${__counter(true,i)}:只統計該用戶的迭代次數,
${__counter(false,i)}:統計所有用戶的迭代次數,
${__threadNum}_${__counter(true,i):統計每個線程下,每個用戶的迭代次數。
可以看出,【點贊】請求執行了1次,【查看】請求執行了9次
2、通過switch controller來實現實現
switch controller類似於程序中的switch函數,該Controller根據給定的值n(可以使用參數)選擇執行其下的第n個子節點。
JMeter取樣器按順序編號,第一個取樣器(請求)編號為0,第二個為1,以此類推。
如果指定的編號超出了下面的節點數或者不指定,則運行第0個取樣器。
如上例,我們給定的值n應該是{0,1,1,1,1,1,1,1,1,1};
0代表執行第一個取樣器,也就是其下的第一個子節點——【點贊】請求; 1代表執行第二個取樣器,也就是其下的第一個子節點——【查看】請求。
為了更符合線上實際場景,我們用一個random隨機數來控制請求的執行順序,而不是像方法1那樣順序執行。
操作步驟如下:
①添加BeanShell 取樣器及腳本
右擊【線程組】→【添加】→【取樣器】→【BeanShell 取樣器】→添加如下腳本
import java.util.Random; //設置比例為1:9
int[] values = {0,1,1,1,1,1,1,1,1,1}; //利用random隨機函數來按照比例隨機執行http請求
int size = values.length; Random rd = new Random(); int n = rd.nextInt(size-1); System.out.println("value:"+values[n]); //新建參數"SWITCH_VALUE",並將通過隨機函數得到的取樣器賦值給參數
vars.put("SWITCH_VALUE",String.valueOf(values[n]));
②添加Switch控制器
右擊【線程組】→【添加】→【邏輯控制器】→【switch 控制器】→設置控制變量,即上一步腳本里設置的參數“SWITCH_VALUE”→運行線程組
可以看出,我們共10條請求,【點贊】1條,【查看】9條。與我們最初設置的1:9的比例一致。
3、通過自定義隨機變量+if控制器來實現
如上場景,我們可以通過Java腳本自定義一個min-max的隨機數,然后用if控制器來控制發送哪個請求。
如上場景,點贊與查看是1:9,我們可以定義一個生成1-10的隨機數,用if控制器來控制,if 隨機數=1,則執行【點贊】請求,if隨機數>1,則執行【查看】請求。
具體步驟如下:
①自定義隨機變量
選擇線程組→【添加】→【取樣器】→【Java請求】 (因為要寫Java腳本,所以需要先添加Java請求,在Java請求下添加取樣器)
選擇【Java請求】→【添加】→【前置處理器】→【BeanShell PreProcessor】→添加 設置自定義變量的腳本,生成隨機數【randNo】
//.......自定義隨機數的方法一........
import java.util.Random; class JmeterUtil{ public static int getRandNo(int min,int max){ Random random = new Random(); int randNo = random.nextInt(max)%(max-min+1) + min; return randNo; } } int r = JmeterUtil.getRandNo(1,10); vars.put("randNo",r.toString()); //.......自定義隨機數的方法二........
vars.put("randNo","${_Random(1,10)}");
②為每個請求添加if控制器,來控制比例
右擊【點贊】/【查看】請求→【插入上級】→【邏輯控制器】→【如果(If)控制器】→添加隨機數【randNo】的判斷
在這里要注意,這里只能填一個變量來作為判斷條件,而不能直接填【${randNo}=1】,這樣if控制器是無法解析的,所以,我們要內置jexl3函數來實現表達式的計算。
步驟如下:
點擊【工具】→選擇【函數助手對話框】→選擇【jexl3】函數→將表達式填入函數參數的【值】那一列→點擊【生成】→點擊生成的函數即可復制→將復制的函數表達式粘貼在if的判斷條件框里
這里是點贊的if控制器,點贊的比例是1,所以我們的判斷條件為randNo==1。
【查看】請求的if控制器設置同上,只是判斷表達式由【&{randNo}==1】改為【&{randNo}>1】
運行結果如下:
可以看出,比例基本一致,【點贊】請求有2個,【查看】請求有8個,隨機數不是10個數一定是1-10都會出現,所以會出現這種2:8的現象,壓測過程中請求較大,故比例偏差是微乎其微的,可忽略。
4、使用JMeter內置隨機數+if控制語句來實現
具體步驟:
①右擊線程組→【添加】→【配置元件】→【Random Variable】→設置變量名稱、隨機范圍
為每個請求添加if控制器的方法同方法三中的步驟一樣,連變量名都一樣,原樣操作即可。
三、各種方法的優缺點
1、對每個請求設置循環次數。
優點:操作簡單易於實現
缺點:只能順序執行,無法隨機執行
2、通過switch controller來實現實現
優點:
可以隨機執行
缺點:
如果接口較多,比例偏差較大,設置起來比較費勁,例如2:10:88,數組里是2個0,10個1,88個2。
因為每次都要讀一遍BeanShell 取樣器,嚴重影響性能,使結果偏離現實。
3、通過自定義隨機變量+if控制器來實現
優點:可拓展性高,可以根據需求用腳本實現,
缺點:
學習成本高,不適宜新手
性能低,沒執行一次,都要先執行下這個Java腳本
4、使用JMeter內置隨機數+if控制語句來實現
優點:
易上手,操作簡單
性能高,因為用的是JMeter內置隨機數,所以比方法3性能更高一些。
缺點:
可拓展性差,不能根據特殊需求控制隨機變量的隨機性,只能設置一個隨機區間。
所以,
根據經驗,方法4是最適用大眾的按比例壓測的方法。
初入職場熱愛分享的打工人一枚,請大家多多指教~~