經常收到微信好友的各種問題咨詢,今天分享一個比較有代表性的,希望對大家有所幫助。
一位微信好友的提問
問題如下:
問題分析
先簡單介紹下服務端的處理邏輯,關於登錄,服務端的邏輯一般是:校驗用戶名、密碼(可能還有驗證碼,但是壓測環境都會特殊處理),成功后,會根據規則(比如拼接時間戳等字符串、加鹽、加密),生成一個tokenId,然后存入redis;關於依賴登錄的請求,服務端的邏輯一般是:會校驗傳入的tokenId在redis中是否存在,存在,表示用戶已經登錄ok了,否則會返回登錄超時之類的信息;
我們在壓測的時候,有些接口是依賴登錄的,常規操作是:使用僅一次控制器,每個賬號只登錄一次,登錄成功后,正則提取到tokenId,此時就存入了當前線程的變量中,然后把此tokenId作為被壓測接口的入參;
如果是分布式,我們需要手動把登錄用戶名參數化文件拷貝到負載機上(注意:loadrunner是自動把腳本和參數化文件分發到負載機上),此時,多個負載機使用的參數化文件內容是相同的,分布式壓測的時候,如果A負載機的某個線程先使用qzcsbj這個賬號登錄成功,tokenId也存入redis了,壓測過程中,這個線程就會一直使用這個tokenId值,然后B負載機的某個線程也用qzcsbj這個賬號登錄成功,生成新的tokenId,此時會把redis里面A負載機生成的值更新,最后,A負載機上那個線程的請求都會失敗,這就是這位微信好友的問題。
解決方案
方案一:各個負載機上參數化文件內容不一樣,這樣就需要更多的用戶名;
方案二:避免登錄接口的影響,我們可以先單獨操作依賴的請求,把需要獲取的關聯值tokenId存到文件中,被壓測的請求就從這個文件中獲取tokenId,這樣,我們壓測的腳本中就不需要登錄接口了,只有我們的被壓測接口,有人可能會問,tokenId是有有效時間的,那是不是要頻繁獲取tokenId生成文件呢?當然不是,我們可以找開發幫忙把有效時間設置長點,比如24h,這樣,獲取一次,就可以用一天了;負載機參數化文件內容相同,如果被壓測接口是修改操作,會有數據庫鎖等待,甚至鎖等待超時的情況出現(參考這篇推文里的案例:性能測試:通過一個案例告訴你,性能到底要不要熟悉業務邏輯?);
方案三(推薦):基於方案二,各個負載機上參數化文件的內容都不同;
方案實現舉例
下面簡單介紹下如何將關聯轉換為參數化:
1、刪除已存在的參數化文件tokenId.txt
注意:因為后面要生成tokenId.txt這個文件,如果這個文件存在,我們先刪除。
2、生成參數化的文件tokenId.txt
這里只是演示,假設需要100個賬號,線程數設置為100,循環次數設置為1,即每個線程運行一次
a.登錄接口需要的csv參數化文件userInfo.dat
注意,此參數化文件中有兩列,第一列是卡號,第二列是登錄賬號,下圖抹掉了敏感數據
登錄獲取參數化文件中的登陸賬號userAccount,而卡號cardNumber是被壓測接口需要的參數
b.登錄請求
正則提取tokenId
c.把關聯獲取到的值寫入文件,因為被壓測的接口需要用到tokenId和卡號cardNumber,所以需要把tokenId和卡號配對寫在一行上,第一列是tokenId,第二列是卡號cardNumber
生成的tokenId.txt文件,逗號分隔同一行的tokenId和卡號cardNumber兩列數據,抹掉了敏感數據
最后,如果有N個負載機,就寫個腳本把tokenId.txt的內容拆分為N個文件,比如:tokenId_1.txt,tokenId_2.txt ... tokenId_N.txt,但是,復制到負載機上,文件名都要改為tokenId.txt
name、password為參數化csv文件中的值,加token寫新的csv
FileWriter fstream = new FileWriter("C:\\data.csv",true); //寫入數據到文件 BufferedWriter out = new BufferedWriter(fstream); // ","在csv文檔中就是向右移一個單元格 out.write(vars.get("name")+","+ vars.get("password") +"," + vars.get("token")); //換行 out.write(System.getProperty("line.separator")); out.close(); fstream.close();
csv行數
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; String putNum; int rowNum=0; try { BufferedReader br=new BufferedReader(new FileReader("D:\\apache-jmeter-5.1.1\\bin\\data.csv")); String tmpStr=""; while((tmpStr=br.readLine())!=null) { rowNum++; } rowNum=rowNum-1; } catch (IOException e) { e.printStackTrace(); } vars.put("putNum",String.valueOf(rowNum)); log.info("==========CSV行數:" + rowNum);
3、被壓測接口腳本
被壓測接口腳本略,這里只演示參數化文件這樣,
這樣,被壓測接口就可以用上面生成的關聯參數文件tokenId.txt了,下面變量名稱和生成的tokenId.txt文件中變量順序要一致
好了,就這樣,是不是很簡單?
如有不准之處,或者補充,請文末留言,謝謝。
更多案例:https://www.cnblogs.com/uncleyong/p/14098538.html
猜你喜歡
點擊閱讀☞一篇文章告訴你怎么做性能測試
點擊閱讀☞如何面試性能測試
點擊閱讀☞面試題(造火箭必備技能):請舉例一個最有成就感的性能bug
點擊閱讀☞jmeter5.1分布式壓
點擊閱讀☞性能測試案例:redis獲取不到連接池,Timeout waiting for idle object
點擊閱讀☞性能測試案例:tps波動頻繁
點擊閱讀☞性能測試案例:一個頻繁fgc問題
點擊閱讀☞性能測試案例:獲取不到redis連接池