CentOS 上 Tomcat 连接超时的定位与解决
一、快速定位
- 检查端口监听与进程状态:确认 Tomcat 是否在 8080/8009 等端口监听,是否被其他进程占用。命令示例:
ss -lntp | grep :8080、lsof -i :8080、ps -ef | grep tomcat。若端口未监听或进程异常,优先修复部署与启动问题。
- 排查访问路径与防火墙:确认访问协议与端口一致(HTTP/HTTPS),以及系统防火墙与云安全组已放行对应端口。命令示例:
firewall-cmd --list-ports、firewall-cmd --permanent --add-port=8080/tcp && firewall-cmd --reload。
- 查看关键日志:第一时间检查 $CATALINA_HOME/logs/catalina.out、localhost.log 是否有部署失败、启动异常、OutOfMemoryError、线程阻塞等线索。
- 判断是否“线程池耗尽/假死”:高峰期出现访问超时但进程存在,常见于 maxThreads 不足或长连接未回收。用
jstack <tomcat_pid> 查看线程是否大量阻塞,配合监控工具(如 JVisualVM/JConsole)观察线程与内存。
- 反向代理链路检查:若经 Nginx/Apache 访问,需同步检查代理的 connect/read/send timeout 与后端健康探测配置,避免链路中某一段先超时。
二、常见根因与对应修复
- 线程池与队列不足:默认 maxThreads=200,高并发下新请求排队或被拒绝。建议结合压测适度提升,并合理设置 acceptCount(等待队列)。示例:
maxThreads=400、acceptCount=500(通常建议 acceptCount ≥ maxThreads)。
- 长连接未回收导致“假死”:HTTP/1.1 默认长连接,若 connectionTimeout/keepAliveTimeout 过大或 maxKeepAliveRequests 设置不当,连接长时间占用线程,出现新请求超时。建议缩短 keepAliveTimeout、限制 maxKeepAliveRequests,必要时禁用长连接以快速回收。
- 反向代理超时不匹配:Nginx/Apache 的 proxy_connect_timeout / proxy_read_timeout / proxy_send_timeout 小于 Tomcat 处理时长,会在代理层先超时。需与后端处理耗时对齐(如统一为 60s 或按业务设置更高)。
- 数据库/外部依赖瓶颈:连接池过小、慢 SQL、连接泄漏会拖慢响应直至超时。应优化 JDBC 连接池(如 HikariCP/DBCP)参数与 SQL,设置合理 maxWaitMillis,并排查慢查询。
- 系统资源与网络限制:文件描述符上限过低、内核网络参数保守、SYN 队列/backlog 不足,都会导致新连接建立慢或被丢弃。需提升 ulimit -n、优化 somaxconn/tcp_max_syn_backlog 等。
- JVM/内存问题:堆内存不足引发 GC 停顿 或 OOM,表现为间歇性超时。应合理设置 -Xms/-Xmx、元空间与 GC 策略。
三、关键配置示例
- Tomcat server.xml(示例为 HTTP/1.1 Connector)
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="400"
minSpareThreads="25"
acceptCount="500"
maxKeepAliveRequests="100"
keepAliveTimeout="15000"
redirectPort="8443"
enableLookups="false"
URIEncoding="UTF-8"/>
要点:
- connectionTimeout:建立连接后等待数据的超时(毫秒),如 20000。
- keepAliveTimeout:长连接保持时间(毫秒),如 15000。
- maxKeepAliveRequests:每个长连接最多请求数,建议 100~200,若业务短请求多可适当提高;设置为 1 相当于禁用长连接。
- maxThreads/acceptCount:并发与排队能力,通常 acceptCount ≥ maxThreads。
- 反向代理 Nginx(与后端保持一致的超时)
http {
upstream tomcat_servers {
server 127.0.0.1:8080;
}
server {
listen 80;
location / {
proxy_pass http://tomcat_servers;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
send_timeout 60s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
- 系统层面关键调优(/etc/sysctl.conf,按需逐步调整)
net.core.somaxconn = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_intvl = 2
net.ipv4.tcp_keepalive_probes = 2
net.core.netdev_max_backlog = 3000
应用:sysctl -p 使配置生效。
- 文件描述符与 JVM
- limits.conf:
* soft nofile 65536、* hard nofile 65536
- catalina.sh(示例):
export CATALINA_OPTS="$CATALINA_OPTS -Xms1g -Xmx2g -XX:MaxMetaspaceSize=512m -XX:+UseG1GC"
四、验证与回退
- 基线压测与观测:使用 ab/wrk/jmeter 进行基线压测,观察 RT、95/99 分位、错误率、线程使用率、队列堆积 与 TCP 状态(如 TIME_WAIT/TW_REUSE/TW_RECYCLE 谨慎使用)。
- 逐步调参与 A/B 对比:一次只调整一个关键参数(如 maxThreads 或 keepAliveTimeout),对比前后 p95/p99 与错误率,确认收益再继续。
- 监控与告警:持续采集 Tomcat 线程/请求、JVM GC、系统连接数/负载,设置超时与线程池告警阈值,便于提前发现问题。
- 回退预案:保留一套“稳定配置”基线;变更失败或异常时,按变更单快速回滚到上一个稳定版本。
五、注意事项
- 谨慎开启或依赖 tcp_tw_recycle:在 NAT/LB 或多主机环境中可能导致连接异常,生产环境更推荐 tcp_tw_reuse 配合合理的 tcp_fin_timeout 与业务长连接策略。
- connectionTimeout=0 表示永不超时,存在资源被长时间占用的风险,不建议在生产使用。
- 任何内核参数与文件描述符调整,务必在测试环境验证,并评估对现有业务与稳定性的影响,再推广到生产。