淺談Spring Boot: 介面壓測及簡要優化策略
工程做好之後,需要對介面進行壓力測試。可以自己編寫執行緒池模擬多使用者訪問測試,也可以使用jmeter進行壓測。jmeter的好處是測試方便,並且有完善的結果分析功能。本次採用jmeter進行壓力測試。
1.準備資料,為了測試準備200w條以上的資料。一個簡單的方法是使用下面的sql快速建立。
INSERT INTO table (user_name,address)
SELECT user_name,address FROM table;
但這樣建立的資料不同記錄的重複部分太多,和實際業務不太相符。一般業務上,除了主鍵之外還會有某一個欄位是唯一,比如手機號,使用者名稱等。本次將user_name設定為唯一,簡單採用UUID的方式生成。
@RequestMapping("/create") public Integer createData(Integer password) { if (password != 1024) { return 0; } ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(10,20,1,TimeUnit.MINUTES,new ArrayBlockingQueue<Runnable>(100000),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy()); int max = 1000000; for (int i = 0; i < max; i++) { poolExecutor.execute(() -> { Date now = new Date(); User user = new User(); user.setStatus(0); user.setUserName(UUID.randomUUID().toString().replace("-","")); user.setAddress(""); user.setCreateTime(now); user.setUpdateTime(now); userService.saveUser(user); }); } return 1; }
採用執行緒池技術來生成資料。部分引數參考自己的配置進行設定。我這裡採用核心執行緒數10,最大執行緒數20,阻塞佇列容量10w,拒絕策略CallerRunsPolicy的引數來生成。
資料生成以後,確認下生成數量,可以看到所有的user_name都是不同的。
select count(*),count(distinct user_name) from user
2.改造介面。為了測試方便,使用公共mapper。引入依賴
<dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> </dependency>
修改啟動類MapperScan註解為import tk.mybatis.spring.annotation.MapperScan;
mapper介面繼承extends Mapper,(import tk.mybatis.mapper.common.Mapper;)。這樣就會為mapper生成insert,select等基本方法。
3.測試。
所測試的介面為
@RequestMapping(value = "/hello",method = {RequestMethod.POST}) public List<User> getUser(User user) { return userService.getUserByUser(user); }
開啟jmeter,通過Option選擇中文語言。建立測試計劃,這次僅對介面進行壓力測試。
測試引數選擇userName,並使用隨機生成的UUID,這樣可以保證最終訪問DB時不觸發任何快取。
1.檔案-新建測試計劃
2.編輯-新增-執行緒-執行緒組
3.選中執行緒組,編輯-新增-邏輯控制器-事務控制器
4.選中事務控制器,編輯-新增-取樣器-BeanShell 取樣器
5.選中事務控制器,編輯-新增-HTTP請求
6.選中BeanShell取樣器,將下面程式碼複製到指令碼框裡面,內容即為設定user_name變數為UUID。
import java.util.UUID; UUID uuid1 = UUID.randomUUID(); vars.put("user_name",(uuid1.toString()).toUpperCase().replaceAll("-",""));
7.選中HTTP請求,設定如下,其中引數部分內容為:
名稱 | 值 |
---|---|
userName | ${user_Name} |
這樣就可以將步驟6生成的引數傳遞為HTTP POST請求的引數了。
新增結果樹,彙總報告等,最終結構:
8.選中執行緒組,設定執行緒數等資訊,詳細請參照官網:https://jmeter.apache.org/usermanual/index.html
這裡先設定執行緒數為2000,由於要壓力測試,設定Ramp-up為1秒,即1秒內啟動所有執行緒。
9.啟動執行緒組。在這裡插入圖片描述
10.結果樹裡面可以確認具體每次請求的引數:
彙總報告裡面可以檢視總體資訊:
通過以上步驟,可以初步預估下系統各個介面的吞吐量等資訊。第一次壓測中user_name自動沒有設定索引,可以通過一些方法來提高系統性能:
1.為user_name設定索引。
2.使用redis快取,其一是快取最近檢索資料,其二是將表中所有user_name存入快取(Set),請求到來時首先去快取中檢視是否存在,只有存在的時候才去檢索DB。
3.若資料量過大,可採用布隆過濾器儲存user_name。
4.限流,這裡只說API層面的,guava包下RateLimiterJ;自寫切面+Redis;Spring Cloud GateWay。
工程地址:https://github.com/showsys20/spring-demo-cm.git
以上這篇淺談Spring Boot: 介面壓測及簡要優化策略就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。