關於一個簡單接口的高並發測試與優化記錄


目的

通過測試,了解高並發需求的各處細節,尋找制約因素;為軟件框架 和 硬件架構提供優化參考。

前述

  • 優化前,目標接口在測試環境的qps為160左右
  • 目標接口的內部邏輯
    • 處理前1:開始計時
    • 處理前2:較驗IP白名單[rpc]
    • 處理:
      • 查詢數據庫並緩存
    • 處理后1:結束計時;提交性能報告[rpc];提交輸入輸出日志[rpc]
      • 日志通過RPC,最終寫入數據庫
  • 目標接口特征:
    • 內部處理簡單
    • 可監測點比較清晰

開始測試

  • 使用一個nio或aio的通道框架測試helloworld

    • 使用本機測試,qps約為:450萬(我的電腦4c 16g)
      • 如果server端的服務線程,加個System.out.println;qps約為:20萬(縮了20多倍)
  • 使用solon.boot.jlhttp,測試helloworld(單機,單實例)

    • 使用本機測試,qps 約為:5萬(我的電腦4c 16g)
    • 使用域局網測試(192.168.8.118),qps約為:2萬(2c 16g)
  • 測試目標接口 getAppByID (服務端為單機單實例;測試端為另一台機,走的是內網)

    • 服務端測試機情況
      • 上面有8個java服務;docker服務(memcached,redis,mysql);
    • 初始測試
      • qps約為:160
    • 去掉三個觸發器(即前后處理,相當於Spring的過濾器)
      • -不用緩存,qps約為:600
      • +memcached,qps約為:1萬(memcached 在本機,應該有優勢;否則可能差些)
      • +二級緩存,qps約為:1.5萬
      • 從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萬(::從900提到1.1萬了;不同時間測值會有波動)
    • +記性能 +記日志 +白名單較驗,qps約為:320

優化三

  • 性能記錄,改為本地收集 + 5秒間隔提交(可稱為緩沖模式)

    • +記性能 +白名單較驗,qps約為:6000(應該還有優化空間)
    • +記性能 +記日志 +白名單較驗,qps約為:800
  • 日志級別動態可控,可在非必要時控制日志提交量(對於業務系統,這個控制是非常之必要)

    //日志級別動態切換控制
    WaterClient.Config.subscribe("sponge", (set)->{
        int level = set.get("rock_log_level").getInt();
        WaterLogger.setLevel(Level.of(level));
    });
    

優化四

  • 優化性能記錄的緩沖器,改為1秒間隔提交
    • +記性能 +白名單較驗,qps約為:15000(::對業務處理幾乎無影響了)
  • 日志改為本地隊列收集+批量打包提交(可稱為管道模式)
    • +記性能 +記日志 +白名單較驗
      * 空時1秒間隔,單包最多100個日志:qps約為:5000
      * 空時1秒間隔,單包最多200個日志:qps約為:10000

后續嘗試

  • 實驗一:
    • 對比測試:日志管道模式提交,與代理抓取模式的差異

分析總結

  • 減少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"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM