文章目录
Tomcat优化
高并发、资源利用效率和稳定性等因素。为了提升 Tomcat 的运行效率和稳定性,我们可以从操作系统、Tomcat 配置文件以及 Java 虚拟机(JVM)三个方面进行优化。
Tomcat 配置文件参数优化
Tomcat 的配置文件主要是 conf/server.xml
,其中 <Connector>
标签是优化的重点之一。以下是一些常用的优化参数及其解释:
redirectPort
:当 HTTP 连接器接收到 HTTPS 请求时,重定向到的端口。maxThreads
:Tomcat 可创建的最大线程数,即支持的最大并发连接数。默认值可能较低,根据服务器硬件和负载情况调整。minSpareThreads
:Tomcat 启动时初始化的线程数,即最小空闲线程数。maxSpareThreads
:最大备用线程数,一般不需要设置,默认为-1(无限制)。processorCache
:线程池中的线程在空闲时会被缓存起来,以便快速响应新的请求。这个值可以根据maxThreads
设定或设为-1。URIEncoding
:Tomcat 容器的 URL 编码格式,通常设置为 UTF-8。connectionTimeout
:网络连接超时时间,单位毫秒。enableLookups
:是否反查域名。为了提高性能,应设置为false
。disableUploadTimeout
和connectionUploadTimeout
:与上传文件相关的超时设置。acceptCount
:当所有处理请求的线程都在使用时,可接受的最大请求队列长度。maxKeepAliveRequests
:长连接的最大请求数。compression
、compressionMinSize
、compressableMimeType
:控制是否对响应进行 GZIP 压缩及其相关设置。
示例配置
以下是一个示例配置,展示了如何在 server.xml
文件中调整 <Connector>
的参数:
vim /usr/local/tomcat/conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
<!-- 以下配置项在第71行之后插入 -->
minSpareThreads="50"
<!-- 设置Tomcat启动时创建的最小空闲线程数,确保始终有一定数量的线程准备处理请求 -->
enableLookups="false"
<!-- 禁用DNS查询,提高处理请求的速度 -->
disableUploadTimeout="true"
<!-- 禁用上传超时,允许长时间上传文件 -->
acceptCount="300"
<!-- 设置当所有线程都在处理请求时,允许的最大连接队列长度 -->
maxThreads="500"
<!-- 设置Tomcat能够创建的最大线程数,即最大并发处理能力 -->
processorCache="500"
<!-- 设置处理器缓存大小,用于提升并发请求处理能力 -->
URIEncoding="UTF-8"
<!-- 设置URL编码格式为UTF-8,确保正确处理各种字符集 -->
maxKeepAliveRequests="100"
<!-- 设置一个长连接上允许的最大请求数,超过此数将关闭连接 -->
compression="on"
<!-- 启用响应数据的GZIP压缩,减少传输数据量 -->
compressionMinSize="2048"
<!-- 设置响应报文的最小压缩大小,只有大于此值的报文才会被压缩 -->
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png"
<!-- 指定可以进行压缩的MIME类型 -->
/>
查看 Tomcat 线程:
在 Linux 系统中,你可以使用 ps
命令结合 -T
和 -p
选项来查看指定 Tomcat 进程的线程信息:
ps -T -p <PID>
这里 <PID>
是 Tomcat 进程的 ID。这个命令会列出该进程下所有的线程及其相关信息。
你的配置和解释已经很详细了,但有一些地方需要根据现代JVM(特别是从Java 8开始)的实际情况进行调整和澄清。下面是对你原始配置和说明的详细整理及更新:
Tomcat JVM 参数配置
对于2C4G(2核CPU,4GB内存)的服务器环境,以下是一个推荐的JVM配置示例,适用于Tomcat运行在Java 8或更高版本上:
vim /usr/local/tomcat/bin/catalina.sh
配置添加在 Tomcat 的 bin 目录下 catalina.sh 里,位置在 cygwin=false 前。
# 在 catalina.sh 中设置 JAVA_OPTS
JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m -Xmn768m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/tomcat/temp/oom.hprof -XX:ParallelGCThreads=2 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Djava.awt.headless=true -XX:+DisableExplicitGC"
# 确保这行在 cygwin=false 之前
cygwin=false
参数解释
- -server:启用Server模式的JVM,适用于长时间运行的服务端应用。一定要作为第一个参数,在多个CPU时性能佳。
- -Xms:堆内存的初始大小,是分配JVM的初始内存,默认为物理内存的1/64。一般来讲,此值设的大点,程序会启动的快一点。
- -Xmx:堆内存的最大大小,是分配JVM的最大内存,默认为物理内存的1/4。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。
- 默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。
- 因此建议-Xms与-Xmx设成一样的值,均设为物理内存的一半。其目的是为了能够在java垃圾回收机制清理完堆区内存后不需要重新计算堆区内存的大小而浪费资源。
- -Xmn:堆内新生代的大小,通过这个值也可以得到老生代的大小:-Xmx减去-Xmn。官方推荐配置为整个堆的 3/8。
- 堆区进一步细化分为:新生代、中生代、老生代。
- java中每新new一个对象所占用的内存空间就是新生代的空间,当java垃圾回收机制对堆区进行资源回收后,那些新生代中没有被回收的资源将被转移到中生代,中生代的被转移到老生代。
- 整个JVM堆大小 = 新生代大小 + 老生代大小 + 永久代大小
- -Xss:设置每个线程可使用的内存大小,即栈的大小。一般情况下,设置256k就足够了,此配置将会影响此进程中并发线程数的大小。
- -XX:ParallelGCThreads:配置并行收集器的线程数,即:同时有多少个线程一起进行垃圾回收。当 CPU 数量小于8,此值建议配置等于 CPU 数量。
-XX:PermSize:设置非堆内存初始值,即持久代内存大小,默认是物理内存的1/4
-XX:MaxPermSize:最大非堆内存的大小,即最大持久代内存大小,默认是物理内存的1/4
- 非堆区内存是不会被java垃圾回收机制进行处理的,且最大堆内存与最大非堆内存的和不能超出操作系统的可用内存。
- XMX和XMS设置一样大,MaxPermSize和PermSize设置一样大,这样可以减轻伸缩堆大小带来的压力。
- -XX:+HeapDumpOnOutOfMemoryError 和 -XX:HeapDumpPath:当发生内存溢出时,自动导出堆转储文件,有助于分析内存泄漏问题。
- -XX:+UseG1GC:从Java 7 Update 4及更高版本开始,推荐使用G1垃圾收集器(Garbage-First)。它比CMS收集器(在Java 9中被标记为废弃)提供了更好的性能和更短的停顿时间。
- -XX:MaxGCPauseMillis:尝试控制垃圾收集的最大停顿时间(以毫秒为单位)。注意,这是一个目标值,JVM会尽力实现,但不保证总是能达到。
- -Djava.awt.headless=true:对于不需要图形用户界面的服务器环境,这个设置可以避免AWT尝试加载图形库。
- -XX:+DisableExplicitGC:禁用显式垃圾收集调用,防止
System.gc()
被误调用,这可能导致不必要的性能下降。
注意
- 永久代(PermGen):从Java 8开始,永久代(PermGen space)被元空间(Metaspace)所取代。因此,
-XX:PermSize
和-XX:MaxPermSize
参数不再使用,取而代之的是-XX:MetaspaceSize
和-XX:MaxMetaspaceSize
。对于大多数应用来说,默认设置(元空间大小根据需要动态增长)就足够了,除非你有特殊需求。 - CMS收集器:在Java 9及更高版本中,CMS收集器已被标记为废弃,并在Java 14中被完全移除。因此,如果你计划使用较新版本的Java,请考虑使用G1或其他收集器。
- 内存分配:确保JVM的内存设置不会超出物理内存的限制,否则可能会导致系统交换(swapping),这会严重影响性能。
总结
Tomcat 配置文件参数优化 (server.xml
)
在 Tomcat 的主配置文件 server.xml
中,可以调整多个参数以优化性能。以下是一些常用的优化参数及其说明:
1. 线程池参数
- maxThreads: 最大线程数,默认值为 200。根据服务器负载和业务需求调整。
- minSpareThreads: 最小空闲线程数,默认值为 10。可根据实际情况调整以减少创建新线程的开销。
- maxSpareThreads: 最大备用线程数,默认值为 -1(无限制)。一般不需要设置,除非有特殊需求。
2. 网络连接参数
- URIEncoding: 指定 Tomcat 容器的 URL 编码格式,如
UTF-8
。 - connectionTimeout: 网络连接超时时间,单位毫秒,默认值为 20000 毫秒。
- acceptCount: 当所有请求处理线程都忙时,可接受的连接队列长度,默认值为 100。
3. 性能优化参数
- enableLookups: 是否通过反查域名来获取主机名,建议设置为
false
以提高性能。 - compression: 是否对响应数据进行 GZIP 压缩,建议设置为
on
或force
以减少传输数据量。 - compressionMinSize: 压缩响应的最小值,默认为 2048 字节。
- compressableMimeType: 指定需要压缩的 MIME 类型。
Java 虚拟机(JVM)调优
Tomcat 作为 Java 程序,运行在 JVM 上,因此 JVM 的调优对 Tomcat 性能至关重要。以下是一些常用的 JVM 启动参数:
1. 堆内存设置
- -Xms: 设置 JVM 初始化堆内存大小,建议与
-Xmx
设置相同值以避免内存波动。 - -Xmx: 设置 JVM 最大堆内存大小,建议设置为物理内存的 50% 左右。
2. 新生代和老年代设置
- -XX:NewSize 和 -XX:MaxNewSize: 分别设置新生代初始大小和最大大小。
- -Xmn: 新生代大小(Eden + 2*Survivor),可替代
-XX:NewSize
和-XX:MaxNewSize
。 - -XX:SurvivorRatio: Eden 区与 Survivor 区的比例。
3. 垃圾收集器设置
- -XX:+UseSerialGC: 使用串行垃圾收集器。
- -XX:+UseParallelGC 和 -XX:+UseParallelOldGC: 使用并行垃圾收集器,分别针对新生代和老年代。
- -XX:+UseConcMarkSweepGC 和相关参数: 使用 CMS 垃圾收集器,适用于对停顿时间敏感的应用。
4. 其他性能优化参数
- -XX:+UseBiasedLocking: 启用偏向锁优化。
- -XX:+DisableExplicitGC: 禁止程序中显式调用
System.gc()
。 - -XX:+UseCMSInitiatingOccupancyOnly 和 -XX:CMSInitiatingOccupancyFraction: 控制 CMS 垃圾收集器的触发时机。
常见错误及解决方法
- Java Heap Space 溢出
- 错误:
java.lang.OutOfMemoryError: Java heap space
- 解决方法: 调整
-Xms
和-Xmx
的值,增加 JVM 堆内存大小。
- 错误:
- PermGen Space 溢出
- 错误:
java.lang.OutOfMemoryError: PermGen space
- 解决方法: 在 JDK 8 之前,使用
-XX:MaxPermSize
设置永久代大小;JDK 8 及以上版本已移除永久代,使用元空间(Metaspace)。
- 错误:
- StackOverflowError
- 错误:
java.lang.StackOverflowError
- 解决方法: 检查并修改导致栈溢出的代码,如减少递归深度、优化函数调用等。
- 错误:
Tomcat多实例部署
部署多个Tomcat实例可以在同一台服务器上运行多个独立的Web应用,提高资源利用率和系统灵活性。
1. 安装JDK和Tomcat
首先,确保已安装JDK。然后下载并解压Tomcat到指定目录,并创建两个Tomcat实例的目录结构。
cd /opt
tar zxvf apache-tomcat-9.0.16.tar.gz
mkdir /usr/local/tomcat
mv apache-tomcat-9.0.16 /usr/local/tomcat/tomcat1
cp -a /usr/local/tomcat/tomcat1 /usr/local/tomcat/tomcat2
2. 配置Tomcat环境变量
编辑/etc/profile.d/tomcat.sh
文件,为每个Tomcat实例设置独立的环境变量。
vim /etc/profile.d/tomcat.sh
# tomcat1
export CATALINA_HOME1=/usr/local/tomcat/tomcat1
export CATALINA_BASE1=/usr/local/tomcat/tomcat1
export TOMCAT_HOME1=/usr/local/tomcat/tomcat1
# tomcat2
export CATALINA_HOME2=/usr/local/tomcat/tomcat2
export CATALINA_BASE2=/usr/local/tomcat/tomcat2
export TOMCAT_HOME2=/usr/local/tomcat/tomcat2
使环境变量生效:
source /etc/profile.d/tomcat.sh
3. 修改Tomcat配置文件
编辑第二个Tomcat实例的server.xml
文件,确保各实例的端口号不冲突。
vim /usr/local/tomcat/tomcat2/conf/server.xml
# 修改Server端口
<Server port="8006" shutdown="SHUTDOWN">
# 修改HTTP Connector端口
<Connector port="8081" protocol="HTTP/1.1">
# 修改AJP Connector端口
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
4. 更新启动和停止脚本
编辑每个Tomcat实例的startup.sh
和shutdown.sh
文件,添加相应的环境变量。
# 对于tomcat1
vim /usr/local/tomcat/tomcat1/bin/startup.sh
export CATALINA_BASE=$CATALINA_BASE1
export CATALINA_HOME=$CATALINA_HOME1
export TOMCAT_HOME=$TOMCAT_HOME1
vim /usr/local/tomcat/tomcat1/bin/shutdown.sh
export CATALINA_BASE=$CATALINA_BASE1
export CATALINA_HOME=$CATALINA_HOME1
export TOMCAT_HOME=$TOMCAT_HOME1
# 对于tomcat2
vim /usr/local/tomcat/tomcat2/bin/startup.sh
export CATALINA_BASE=$CATALINA_BASE2
export CATALINA_HOME=$CATALINA_HOME2
export TOMCAT_HOME=$TOMCAT_HOME2
vim /usr/local/tomcat/tomcat2/bin/shutdown.sh
export CATALINA_BASE=$CATALINA_BASE2
export CATALINA_HOME=$CATALINA_HOME2
export TOMCAT_HOME=$TOMCAT_HOME2
5. 启动Tomcat实例
分别启动两个Tomcat实例,并检查端口监听情况。
/usr/local/tomcat/tomcat1/bin/startup.sh
/usr/local/tomcat/tomcat2/bin/startup.sh
netstat -natp | grep java
6. 浏览器访问测试
通过浏览器访问两个Tomcat实例,验证是否正常运行。
http://192.168.80.101:8080
http://192.168.80.101:8081
注意
- 确保每个Tomcat实例的端口号唯一,避免冲突。
- 在修改配置文件和脚本时,务必小心谨慎,防止误操作导致服务中断。
- 定期检查和更新Tomcat实例及其依赖库,确保系统安全性和稳定性。