首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Tomcat 壓力測試實戰:acceptCount 參數調優解決連線失敗

     編輯:Java 相關知識

實測 Tomcat 預設配置下,併發 100 執行緒正常,**101 以上大量連線失敗**。經排查為 acceptCount 參數過小,調整後 150 執行緒零失敗通過。本文記錄完整測試代碼、現象分析與調優過程。

現象重現

  • MaxThreads=100 → 正常
  • MaxThreads=101+ → **連線失敗激增**
  • 初步判斷:acceptCount(等待隊列長度)不足

調優動作

修改 server.xml Connector 節點:


<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" 
           redirectPort="8443" acceptCount="200" />

acceptCount:當所有請求處理執行緒忙碌時,新連線進入**等待隊列**的最大長度。隊列滿則拒絕連線(Connection refused)。

壓測代碼完整版


package com.ask.pressure;

import java.io.*;
import java.net.*;

public class AskPressure {
    private static final String URL = "https://192.168.0.59:8080/ask/index.html";
    private static final int THREADS = 150;
    private static int error = 0;
    private static int remaining = THREADS;
    private static long startTime;

    public static void main(String[] args) {
        WorkThread[] threads = new WorkThread[THREADS];
        for (int i = 0; i < THREADS; i++) threads[i] = new WorkThread();

        startTime = System.currentTimeMillis();
        for (WorkThread t : threads) t.start();
    }

    static class WorkThread extends Thread {
        public void run() {
            long reqStart = System.currentTimeMillis();
            try {
                URL u = new URL(URL);
                HttpURLConnection conn = (HttpURLConnection) u.openConnection();
                conn.setUseCaches(false);
                conn.setRequestProperty("Content-type", "text/html; charset=UTF-8");
                conn.connect();

                // 讀取完整回應
                try (InputStream is = conn.getInputStream();
                     BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
                    String line;
                    while ((line = reader.readLine()) != null) { /* consume */ }
                }
            } catch (Exception e) {
                synchronized (AskPressure.class) { error++; }
                e.printStackTrace();
            } finally {
                synchronized (AskPressure.class) {
                    remaining--;
                    System.out.printf("剩餘 %d 執行緒, 耗時 %d ms%n", 
                        remaining, System.currentTimeMillis() - startTime);
                    if (remaining == 0) {
                        System.out.printf("總耗時:%d ms%n", System.currentTimeMillis() - startTime);
                        System.out.printf("連線失敗:%d%n", error);
                    }
                }
            }
        }
    }
}

測試結果(調優後)


剩餘 9 執行緒, 耗時 1484 ms
剩餘 5 執行緒, 耗時 1547 ms
...
剩餘 0 執行緒, 耗時 1578 ms
總耗時:1578 ms
連線失敗:0

**150 併發、零失敗、平均 10ms/請求**,驗證調優有效。

關鍵參數關係圖

**公式**:maxConnections ≈ maxThreads + acceptCount(粗略上限)。

延伸調優方向

  1. 啟用 NIO2 或 APR 連接器提升高併發吞吐
  2. 調整 minSpareThreads/maxSpareThreads 減少執行緒建銷開銷
  3. 壓測工具升級:JMeter、Gatling、wrk 支援更真實場景
  4. 監控指標:CPU、記憶體、GC、執行緒池狀態、錯誤率、P99 延遲

一行配置修改解決併發瓶頸,凸顯理解容器參數語義的重要性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
參數含義建議
maxThreads最大請求處理執行緒數依 CPU 核心與 IO 特性調整(如 200-500)
acceptCount等待隊列長度(作業系統層面)≥ maxThreads,尖峰緩衝(如 200-1000)
connectionTimeout閒置連線超時 (ms)20000 (20s) 為預設合理值