目的
通過測試瞭解高併發的各處細節,尋找制約因素;為軟硬架構設計提供優化參考。
前述
- 優化前,該介面在測試環境的qps為140左右
- 該介面的內部邏輯
- 處理前1:開始計時
- 處理前2:較驗IP白名單
- 處理:
- 查詢資料庫並快取
- 處理後1:結束計劃,並提交日誌(用於形成效能報告)
- 日誌通過REST API,最終寫入資料庫
- 該介面特徵:
- 內部處理簡單
- 可優化點比較清楚
開始測試
-
使用一個nio或aio的通道框架測試helloworld
- 使用本機測試,qps約為:450萬(我的電腦 macbook pro 4c 16g)
- 如果server端的服務執行緒,加個
System.out.println
;qps估計要降一半(親自跑過)
- 如果server端的服務執行緒,加個
- 使用本機測試,qps約為:450萬(我的電腦 macbook pro 4c 16g)
-
使用solon.boot.jlhttp,測試helloworld(單機,單例項)
- 使用本機測試,qps 約為:5萬(我的電腦 macbook pro 4c 16g)
- 使用域局網測試(192.168.8.118),qps給為:2萬(2c 4g 虛擬機器)
-
測試getAppByID(服務端為單機單例項;測試端為另一臺機,走的是內網)
- 服務端測試機情況
- 上面有8個java服務;docker服務(memcached,redis,mysql);
- 初始測試
- qps約為:140
- 去掉三個觸發器
- -不用快取,qps約為:600
- +memcached,qps約為:1萬(memcached 在本機,應該有優勢;否則可能差些)
- +二級快取(一級為本地快取),qps約為:1.4萬
從DB角度思考,如果涉及寫。。。qps只能靠DB的硬體提升了(量大時,還要靠分庫分表)
- 加上觸發器 + 二級快取
- +記效能,qps約為:750
- +記效能 +記日誌,qps約為;240(非同步http提交日誌;可能儲存在本機會有較大負影響;
sev->http->db->磁碟
) - +記效能 +記日誌 +白名單較驗,qps約為:160
- +白名單較驗,qps約為:900
- 服務端測試機情況
優化一
- 將okhttp非同步,改為執行緒池加同步(okhttp自帶的非同步,因為有融斷機制效能差些)
- +記效能 +記日誌,qps約為;320(非同步http提交日誌;明明是非同步了,為什麼還這麼低?因為還是有IO)
- +記效能 +記日誌 +白名單較驗,qps約為:200
優化二
- 為白名單增加10s本地快取
- +白名單較驗,qps約為:1.1萬
- +記效能 +記日誌 +白名單較驗,qps約為:320
優化三
- 效能記錄,改為本地收集 + 5秒間隔提交
- +記效能 +白名單較驗,qps約為:6000(應該還有優化空間)
- +記效能 +記日誌 +白名單較驗,qps約為:800
- 日誌級別動態可控,可在非必要時控制日誌提交量
- 日誌約等於可沒有...進而減少這部分的IO(對於業務系統,這個控制是非常之必要)
後續方案嘗試
- 優化四:
- 將日誌記錄,調整為批量隔秒提交;進一步降低框架對應用的併發影響
- 實驗一:
- 對比測試:日誌管道模式提交,與代理抓取模式的差異
分析總結
- 減少IO次數(主要是網路寫IO),可以大大提搞QPS。。。此為王道
- 何為IO?一次IO輸出過程:
- 應用空間 - > 核心空間 -> 裝置暫存器
- 減少次數或避免IO可大大提高併發(像System.out.print...就是,都會影響高併發)
- IO的總量有限...
- 我們經常會看到,cpu、記憶體很底,但是併發壓不上去。。。就是大量的IO在排隊
- 或者程式在一段時間失去了響應,過段時間又好了。。。也是大量的IO在排隊
- 業務的程式,基本上是IO密集型的
- 不管是多執行緒,還是非同步。。。但IO總量有限
- 之前一直以為,非同步寫日誌對併發沒什麼影響;對單次請求效能無影響,但會佔用IO資源
附:
- 工具安裝
# centos 版
yum install -y https://github.com/scutse/wrk-rpm/releases/download/4.1.0/wrk-4.1.0-1.el7.centos.x86_64.rpm
# mac 版
brew install wrk
- 測試程式碼
wrk -t10 -c200 -d10s --latency "http://10.0.0.79:1013/getAppByID?appID=10970"