實測 Tomcat 預設配置下,併發 100 執行緒正常,**101 以上大量連線失敗**。經排查為 acceptCount 參數過小,調整後 150 執行緒零失敗通過。本文記錄完整測試代碼、現象分析與調優過程。
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/請求**,驗證調優有效。
| 參數 | 含義 | 建議 |
|---|---|---|
| maxThreads | 最大請求處理執行緒數 | 依 CPU 核心與 IO 特性調整(如 200-500) |
| acceptCount | 等待隊列長度(作業系統層面) | ≥ maxThreads,尖峰緩衝(如 200-1000) |
| connectionTimeout | 閒置連線超時 (ms) | 20000 (20s) 為預設合理值 |