Tomcat在Linux下的性能调优技巧
Tomcat在Linux环境中的性能调优需从系统底层优化、Tomcat配置调整、JVM内存与垃圾回收优化、线程池优化及监控与持续改进五大维度综合实施,以下是具体技巧:
Tomcat处理高并发连接时,可能因文件描述符(FD)数量不足导致请求被拒绝。需通过以下命令调整系统级FD限制:
# 查看当前FD限制
ulimit -n
# 临时设置为65535(仅当前会话有效)
ulimit -n 65535
# 永久生效:编辑/etc/security/limits.conf,添加
* soft nofile 65535
* hard nofile 65535
调整TCP缓冲区大小和连接超时设置,提升网络吞吐量与连接复用率:
# 编辑/etc/sysctl.conf,添加以下参数
net.ipv4.tcp_rmem = 4096 87380 16777216 # 接收缓冲区最小/默认/最大值(字节)
net.ipv4.tcp_wmem = 4096 87380 16777216 # 发送缓冲区最小/默认/最大值
net.ipv4.tcp_fin_timeout = 30 # TIME_WAIT状态超时时间(秒)
net.ipv4.tcp_tw_reuse = 1 # 允许复用TIME_WAIT状态的连接
net.core.rmem_max = 16777216 # 接收缓冲区最大值
net.core.wmem_max = 16777216 # 发送缓冲区最大值
# 应用配置
sysctl -p
降低vm.swappiness(默认60)可减少系统使用交换空间的频率,优先使用物理内存,提升I/O性能:
# 查看当前值
cat /proc/sys/vm/swappiness
# 临时设置为10(0-100,值越低越倾向于使用物理内存)
echo 10 > /proc/sys/vm/swappiness
# 永久生效:编辑/etc/sysctl.conf
vm.swappiness = 10
优先使用NIO(非阻塞IO)或HTTP/2协议替代传统HTTP/1.1,提升高并发下的吞吐量。在server.xml中配置:
<!-- NIO连接器(Tomcat默认) -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
<!-- HTTP/2协议(需Tomcat 9+,并配置SSL) -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
sslEnabled="true"
keystoreFile="/path/to/keystore.jks"
keystorePass="changeit"
maxThreads="200" />
调整maxThreads(最大线程数)、minSpareThreads(最小空闲线程数)、acceptCount(排队请求数)等参数,平衡并发处理能力与资源消耗:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="200" <!-- 最大线程数(根据CPU核心数调整,建议2*CPU核心数~4*CPU核心数) -->
minSpareThreads="50" <!-- 最小空闲线程数(避免频繁创建线程) -->
maxSpareThreads="100" <!-- 最大空闲线程数(避免过多闲置线程消耗资源) -->
acceptCount="1000" <!-- 排队请求数(当所有线程忙碌时,允许排队的请求数,超过则拒绝) -->
enableLookups="false" <!-- 禁用DNS查询(加快请求处理) -->
compression="on" <!-- 开启GZIP压缩(减少传输数据量) -->
compressionMinSize="1024"
compressableMimeType="text/html,text/xml,text/css,text/javascript,application/json" />
关闭Tomcat中不必要的功能,减少资源消耗:
server.xml中的AJP Connector;web.xml中添加<init-param><param-name>listings</param-name><param-value>false</param-value></init-param>;根据应用内存需求调整JVM堆内存,避免频繁GC。建议将-Xms(初始堆)与-Xmx(最大堆)设置为相同值,减少堆扩容带来的性能波动:
# 编辑Tomcat的bin/catalina.sh(Linux)或bin/catalina.bat(Windows)
JAVA_OPTS="-Xms2G -Xmx2G" # 初始堆2GB,最大堆2GB(根据服务器物理内存调整,建议不超过物理内存的80%)
JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC" # 启用G1GC
JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=200" # 设置最大GC停顿时间(毫秒)
JAVA_OPTS="$JAVA_OPTS -XX:InitiatingHeapOccupancyPercent=45" # 触发并发GC的堆占用率阈值
JDK 8及以上版本使用元空间(Metaspace)替代永久代(PermGen),需调整其大小以避免OutOfMemoryError: Metaspace:
JAVA_OPTS="$JAVA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
通过Executor元素定义自定义线程池,并在Connector中引用,实现更灵活的线程管理:
<!-- 定义线程池 -->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="500" <!-- 最大线程数(根据服务器硬件调整) -->
minSpareThreads="50" <!-- 最小空闲线程数 -->
maxIdleTime="60000" <!-- 线程空闲时间(毫秒,超过则销毁) -->
prestartMinSpareThreads="true"/> <!-- 启动时预创建最小空闲线程 -->
<!-- 在Connector中引用线程池 -->
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
通过JMX或VisualVM监控线程池的运行情况(如活跃线程数、队列大小、拒绝请求数),根据监控结果调整maxThreads和acceptCount:
activeThreads长期接近maxThreads,说明线程池容量不足,需增加maxThreads;queueSize经常满,说明队列容量不足,需增加maxQueueSize(默认无界,建议设置上限)。top(查看CPU/内存使用率)、free -h(查看内存使用情况)、netstat -tulnp | grep java(查看网络连接);使用压力测试工具(如ab、wrk、JMeter)模拟高并发场景,评估优化效果:
# 使用ab测试8080端口的并发性能
ab -n 10000 -c 100 http://localhost:8080/ # 发送10000个请求,并发100
根据测试结果(如QPS、响应时间、错误率)调整线程池、JVM或系统参数。
性能优化是持续过程,需根据应用负载变化(如用户量增长、业务逻辑变更)定期复查配置,调整参数。例如:
maxThreads和Xmx;MaxMetaspaceSize;