Tomcat 连接器配置
Connector Configuration
概述
Tomcat连接器是处理客户端请求的核心组件,负责接收、解析和响应HTTP/HTTPS/AJP请求。本文将详细介绍各种连接器类型的配置方法、性能优化技巧和最佳实践。
1. 连接器类型概览
1.1 连接器协议类型
Tomcat连接器类型
├── HTTP连接器
│ ├── HTTP/1.1 (默认)
│ ├── HTTP/2
│ └── WebSocket
├── 实现类型
│ ├── NIO (默认)
│ ├── NIO2
│ ├── APR/Native
│ └── BIO (已废弃)
└── 特殊协议
├── AJP/1.3
└── gRPC (扩展)
1.2 连接器选择指南
性能对比表
┌─────────────┬─────────┬─────────┬─────────┬─────────┐
│ 连接器类型 │ 并发性能 │ 内存使用 │ CPU使用 │ 适用场景 │
├─────────────┼─────────┼─────────┼─────────┼─────────┤
│ NIO │ 高 │ 中 │ 中 │ 通用 │
│ NIO2 │ 很高 │ 中 │ 低 │ 高并发 │
│ APR/Native │ 最高 │ 低 │ 最低 │ 生产环境 │
│ AJP │ 高 │ 低 │ 低 │ 代理集成 │
└─────────────┴─────────┴─────────┴─────────┴─────────┘
2. HTTP连接器配置
2.1 基础HTTP连接器
<!-- server.xml - 基础HTTP连接器 -->
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
useBodyEncodingForURI="true" />
2.2 NIO连接器详细配置
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
<!-- 基本参数 -->
maxThreads="200"
minSpareThreads="10"
maxSpareThreads="75"
acceptCount="100"
<!-- 连接参数 -->
connectionTimeout="20000"
keepAliveTimeout="60000"
maxKeepAliveRequests="100"
<!-- 缓冲区设置 -->
socketBuffer="9000"
bufferSize="16384"
<!-- 压缩设置 -->
compression="on"
compressionMinSize="2048"
compressibleMimeType="text/html,text/xml,text/css,text/javascript,application/javascript,application/json,application/xml"
<!-- 其他设置 -->
enableLookups="false"
disableUploadTimeout="true"
maxParameterCount="1000"
maxPostSize="2097152"
maxSavePostSize="4096"
<!-- 执行器引用 -->
executor="tomcatThreadPool" />
2.3 NIO2连接器配置
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
<!-- NIO2特有参数 -->
useSendfile="true"
sendfileSize="1024"
<!-- 性能参数 -->
maxThreads="300"
minSpareThreads="25"
acceptCount="200"
<!-- 异步处理 -->
asyncTimeout="30000"
<!-- 连接管理 -->
connectionTimeout="20000"
keepAliveTimeout="60000"
maxKeepAliveRequests="200"
<!-- SSL配置(如果需要) -->
SSLEnabled="false" />
2.4 APR/Native连接器配置
<!-- 需要先安装tomcat-native库 -->
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11AprProtocol"
<!-- APR特有参数 -->
pollTime="2000"
pollerSize="32768"
useSendfile="true"
sendfileSize="1024"
<!-- 高性能设置 -->
maxThreads="400"
minSpareThreads="25"
acceptCount="300"
<!-- 连接池设置 -->
acceptorThreadCount="2"
acceptorThreadPriority="5"
<!-- 缓冲区优化 -->
socketBuffer="65536"
bufferSize="16384"
<!-- 压缩优化 -->
compression="on"
compressionMinSize="1024" />
3. HTTPS连接器配置
3.1 基础HTTPS配置
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/keystore.jks"
certificateKeystorePassword="changeit"
type="RSA" />
</SSLHostConfig>
</Connector>
3.2 高级HTTPS配置
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200"
SSLEnabled="true"
scheme="https"
secure="true">
<SSLHostConfig protocols="TLSv1.2,TLSv1.3"
ciphers="ECDHE-RSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256"
honorCipherOrder="true"
disableCompression="true"
disableSessionTickets="false"
sessionTimeout="86400">
<!-- RSA证书 -->
<Certificate certificateKeystoreFile="conf/rsa-keystore.jks"
certificateKeystorePassword="rsapass"
certificateKeyAlias="rsa-key"
type="RSA" />
<!-- ECC证书(可选) -->
<Certificate certificateKeystoreFile="conf/ecc-keystore.jks"
certificateKeystorePassword="eccpass"
certificateKeyAlias="ecc-key"
type="EC" />
</SSLHostConfig>
<!-- HSTS设置 -->
<Valve className="org.apache.catalina.valves.HttpHeaderSecurityFilter"
hstsEnabled="true"
hstsMaxAgeSeconds="31536000"
hstsIncludeSubdomains="true" />
</Connector>
3.3 双向SSL认证配置
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
SSLEnabled="true"
scheme="https"
secure="true">
<SSLHostConfig certificateVerification="required"
truststoreFile="conf/truststore.jks"
truststorePassword="trustpass"
truststoreType="JKS"
caCertificateFile="conf/ca-cert.pem">
<Certificate certificateKeystoreFile="conf/server-keystore.jks"
certificateKeystorePassword="serverpass"
type="RSA" />
</SSLHostConfig>
</Connector>
4. AJP连接器配置
4.1 基础AJP配置
<!-- 用于与Apache httpd集成 -->
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443"
address="0.0.0.0"
secretRequired="true"
secret="ajp_secret_key" />
4.2 高性能AJP配置
<Connector port="8009"
protocol="org.apache.coyote.ajp.AjpNioProtocol"
<!-- 连接参数 -->
maxThreads="200"
minSpareThreads="10"
acceptCount="100"
connectionTimeout="600000"
<!-- AJP特定参数 -->
packetSize="65536"
processorCache="200"
<!-- 安全设置 -->
secretRequired="true"
secret="complex_ajp_secret_2023"
allowedRequestAttributesPattern=".*"
<!-- 地址限制 -->
address="127.0.0.1"
<!-- 执行器 -->
executor="ajpThreadPool" />
5. HTTP/2连接器配置
5.1 HTTP/2基础配置
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
SSLEnabled="true"
scheme="https"
secure="true">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"
readTimeout="30000"
keepAliveTimeout="20000"
maxConcurrentStreams="200"
maxConcurrentStreamExecution="20"
initialWindowSize="65535"
allowedTrailerHeaders="x-trace-id" />
<SSLHostConfig protocols="TLSv1.2,TLSv1.3">
<Certificate certificateKeystoreFile="conf/keystore.jks"
certificateKeystorePassword="changeit"
type="RSA" />
</SSLHostConfig>
</Connector>
5.2 HTTP/2性能优化
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
SSLEnabled="true">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"
<!-- 流控制设置 -->
readTimeout="60000"
keepAliveTimeout="30000"
streamReadTimeout="20000"
streamWriteTimeout="20000"
<!-- 并发控制 -->
maxConcurrentStreams="100"
maxConcurrentStreamExecution="200"
<!-- 窗口大小 -->
initialWindowSize="1048576"
<!-- 压缩设置 -->
compressionLevel="6"
compressibleMimeType="text/html,text/css,application/javascript"
<!-- 推送设置 -->
allowedTrailerHeaders="x-request-id,x-correlation-id" />
</Connector>
6. 线程池配置
6.1 共享线程池
<!-- server.xml中定义共享线程池 -->
<Service name="Catalina">
<!-- 通用线程池 -->
<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="300"
minSpareThreads="50"
maxIdleTime="60000"
prestartminSpareThreads="true"
maxQueueSize="100"
threadPriority="5" />
<!-- AJP专用线程池 -->
<Executor name="ajpThreadPool"
namePrefix="ajp-exec-"
maxThreads="150"
minSpareThreads="25"
maxIdleTime="60000" />
<!-- HTTP连接器使用共享线程池 -->
<Connector port="8080"
protocol="HTTP/1.1"
executor="tomcatThreadPool" />
<!-- AJP连接器使用专用线程池 -->
<Connector port="8009"
protocol="AJP/1.3"
executor="ajpThreadPool" />
</Service>
6.2 线程池监控配置
// ThreadPoolMonitor.java
package com.example.tomcat.monitor;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.concurrent.TimeUnit;
public class ThreadPoolMonitor {
private MBeanServer mbs;
public ThreadPoolMonitor() {
this.mbs = ManagementFactory.getPlatformMBeanServer();
}
public void monitorThreadPool() throws Exception {
// 获取线程池信息
ObjectName executorName = new ObjectName(
"Catalina:type=Executor,name=tomcatThreadPool"
);
Integer activeCount = (Integer) mbs.getAttribute(executorName, "activeCount");
Integer poolSize = (Integer) mbs.getAttribute(executorName, "poolSize");
Integer maxThreads = (Integer) mbs.getAttribute(executorName, "maxThreads");
Integer queueSize = (Integer) mbs.getAttribute(executorName, "queueSize");
System.out.println("线程池监控:");
System.out.println("活跃线程数: " + activeCount);
System.out.println("池大小: " + poolSize);
System.out.println("最大线程数: " + maxThreads);
System.out.println("队列大小: " + queueSize);
System.out.println("使用率: " + (activeCount * 100.0 / maxThreads) + "%");
// 检查是否需要调整
if (activeCount * 100.0 / maxThreads > 80) {
System.out.println("警告: 线程池使用率过高!");
}
}
}
7. 连接器性能调优
7.1 连接超时优化
<Connector port="8080"
protocol="HTTP/1.1"
<!-- 连接超时设置 -->
connectionTimeout="20000"
socketTimeout="60000"
<!-- Keep-Alive优化 -->
keepAliveTimeout="15000"
maxKeepAliveRequests="100"
<!-- 异步超时 -->
asyncTimeout="30000"
<!-- 处理器缓存 -->
processorCache="200"
<!-- Socket选项 -->
tcpNoDelay="true"
soLinger="-1"
soTimeout="60000" />
7.2 缓冲区优化
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
<!-- 缓冲区大小 -->
socketBuffer="65536"
bufferSize="16384"
<!-- 文件上传缓冲 -->
maxPostSize="20971520"
maxSavePostSize="8192"
<!-- 请求参数限制 -->
maxParameterCount="10000"
maxHeaderCount="200"
maxHttpHeaderSize="8192"
<!-- Sendfile优化 -->
useSendfile="true"
sendfileSize="1024" />
7.3 压缩优化配置
<Connector port="8080"
protocol="HTTP/1.1"
<!-- 压缩设置 -->
compression="on"
compressionMinSize="1024"
compressibleMimeType="text/html,text/xml,text/css,text/javascript,text/json,application/javascript,application/json,application/xml,application/rss+xml,application/atom+xml,image/svg+xml"
<!-- 压缩级别(APR connector支持) -->
compressionLevel="6"
<!-- 不压缩的用户代理 -->
noCompressionUserAgents="gozilla, traviata"
<!-- 不压缩的文件类型 -->
restrictedUserAgents=".*MSIE.*" />
8. 连接器监控与诊断
8.1 JMX监控配置
<!-- 启用JMX监控 -->
<Connector port="8080"
protocol="HTTP/1.1"
<!-- JMX相关属性 -->
processorCache="200"
socket.txBufSize="25188"
socket.rxBufSize="25188"
socket.tcpNoDelay="true"
<!-- 统计信息收集 -->
enableLookups="false"
maxParameterCount="1000" />
8.2 连接器状态监控
// ConnectorMonitor.java
package com.example.tomcat.monitor;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.Set;
public class ConnectorMonitor {
private MBeanServer mbs;
public ConnectorMonitor() {
this.mbs = ManagementFactory.getPlatformMBeanServer();
}
public void monitorConnectors() throws Exception {
// 查找所有连接器
Set<ObjectName> connectors = mbs.queryNames(
new ObjectName("Catalina:type=Connector,*"), null
);
for (ObjectName connector : connectors) {
String port = connector.getKeyProperty("port");
String protocol = (String) mbs.getAttribute(connector, "protocol");
// 获取连接器统计信息
Integer maxThreads = (Integer) mbs.getAttribute(connector, "maxThreads");
Integer currentThreadCount = (Integer) mbs.getAttribute(connector, "currentThreadCount");
Integer currentThreadsBusy = (Integer) mbs.getAttribute(connector, "currentThreadsBusy");
Long bytesReceived = (Long) mbs.getAttribute(connector, "bytesReceived");
Long bytesSent = (Long) mbs.getAttribute(connector, "bytesSent");
Integer requestCount = (Integer) mbs.getAttribute(connector, "requestCount");
Long processingTime = (Long) mbs.getAttribute(connector, "processingTime");
Integer errorCount = (Integer) mbs.getAttribute(connector, "errorCount");
System.out.println("连接器监控 - 端口: " + port + ", 协议: " + protocol);
System.out.println(" 最大线程数: " + maxThreads);
System.out.println(" 当前线程数: " + currentThreadCount);
System.out.println(" 忙碌线程数: " + currentThreadsBusy);
System.out.println(" 线程使用率: " + (currentThreadsBusy * 100.0 / maxThreads) + "%");
System.out.println(" 接收字节数: " + formatBytes(bytesReceived));
System.out.println(" 发送字节数: " + formatBytes(bytesSent));
System.out.println(" 请求数量: " + requestCount);
System.out.println(" 平均处理时间: " + (processingTime / Math.max(requestCount, 1)) + "ms");
System.out.println(" 错误数量: " + errorCount);
System.out.println(" 错误率: " + (errorCount * 100.0 / Math.max(requestCount, 1)) + "%");
System.out.println();
}
}
private String formatBytes(long bytes) {
if (bytes < 1024) return bytes + " B";
if (bytes < 1024 * 1024) return String.format("%.2f KB", bytes / 1024.0);
if (bytes < 1024 * 1024 * 1024) return String.format("%.2f MB", bytes / (1024.0 * 1024));
return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
}
}
8.3 连接器健康检查
#!/bin/bash
# connector-health-check.sh
TOMCAT_HOST="localhost"
HTTP_PORT="8080"
HTTPS_PORT="8443"
AJP_PORT="8009"
check_http_connector() {
echo "检查HTTP连接器 (端口: $HTTP_PORT)"
response=$(curl -s -o /dev/null -w "%{http_code},%{time_total},%{time_connect}" \
http://$TOMCAT_HOST:$HTTP_PORT/)
http_code=$(echo $response | cut -d',' -f1)
time_total=$(echo $response | cut -d',' -f2)
time_connect=$(echo $response | cut -d',' -f3)
if [ "$http_code" = "200" ]; then
echo " ✓ HTTP连接器正常 (响应时间: ${time_total}s, 连接时间: ${time_connect}s)"
else
echo " ✗ HTTP连接器异常 (状态码: $http_code)"
fi
}
check_https_connector() {
echo "检查HTTPS连接器 (端口: $HTTPS_PORT)"
if timeout 5 bash -c "</dev/tcp/$TOMCAT_HOST/$HTTPS_PORT"; then
echo " ✓ HTTPS端口可访问"
# 检查SSL证书
cert_info=$(echo | openssl s_client -connect $TOMCAT_HOST:$HTTPS_PORT 2>/dev/null | \
openssl x509 -noout -dates 2>/dev/null)
if [ $? -eq 0 ]; then
echo " ✓ SSL证书有效"
echo " $cert_info"
else
echo " ⚠ SSL证书检查失败"
fi
else
echo " ✗ HTTPS端口不可访问"
fi
}
check_ajp_connector() {
echo "检查AJP连接器 (端口: $AJP_PORT)"
if timeout 5 bash -c "</dev/tcp/$TOMCAT_HOST/$AJP_PORT"; then
echo " ✓ AJP端口可访问"
else
echo " ✗ AJP端口不可访问"
fi
}
check_thread_pools() {
echo "检查线程池状态"
# 通过JMX获取线程池信息(需要jmxterm或其他JMX客户端)
if command -v jmxterm.jar &> /dev/null; then
echo "get -b Catalina:type=Executor,name=tomcatThreadPool activeCount" | \
java -jar jmxterm.jar -l service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi -n
else
echo " ⚠ 无法检查线程池(需要JMX客户端)"
fi
}
main() {
echo "=== Tomcat连接器健康检查 $(date) ==="
echo
check_http_connector
echo
check_https_connector
echo
check_ajp_connector
echo
check_thread_pools
echo
echo "=== 检查完成 ==="
}
main
9. 连接器安全配置
9.1 访问控制
<Connector port="8080"
protocol="HTTP/1.1">
<!-- 远程地址过滤 -->
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="192\.168\.1\..*|127\.0\.0\.1"
deny=".*" />
<!-- 请求大小限制 -->
maxPostSize="2097152"
maxSavePostSize="4096"
maxParameterCount="1000"
maxHeaderCount="100"
maxHttpHeaderSize="8192"
<!-- 禁用不安全的HTTP方法 -->
allowTrace="false"
</Connector>
9.2 SSL安全增强
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
SSLEnabled="true">
<SSLHostConfig protocols="TLSv1.2,TLSv1.3"
ciphers="ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-CHACHA20-POLY1305,ECDHE-RSA-CHACHA20-POLY1305"
honorCipherOrder="true"
disableCompression="true"
disableSessionTickets="false"
sessionTimeout="300"
caCertificateFile="conf/ca-bundle.crt"
certificateVerification="none"
revocationEnabled="false">
<Certificate certificateKeystoreFile="conf/keystore.jks"
certificateKeystorePassword="changeit"
certificateKeyAlias="tomcat"
type="RSA" />
</SSLHostConfig>
<!-- 安全头设置 -->
<Valve className="org.apache.catalina.valves.HttpHeaderSecurityFilter"
hstsEnabled="true"
hstsMaxAgeSeconds="31536000"
hstsIncludeSubdomains="true"
hstsPreload="true" />
</Connector>
小结
通过本文学习,你应该掌握:
- 各种连接器类型的选择和配置方法
- HTTP、HTTPS、AJP、HTTP/2连接器的详细配置
- 线程池的配置和监控
- 连接器性能调优技巧
- 连接器监控和诊断方法
- 连接器安全配置最佳实践
- 缓冲区、压缩、超时等优化参数
下一篇文章将详细介绍Tomcat虚拟主机的配置与管理。