【专栏目录】
Tomcat底层原理分析:1.基础环境搭建
Tomcat底层原理分析:2.Tomcat架构分析
Tomcat底层原理分析:3.Jasper引擎
Tomcat底层原理分析:4.Tomcatd的server.xml配置内容解析
Tomcat底层原理分析:5.Web应用配置解析
Tomcat底层原理分析:6.Tomcat中对JVM的配置解析
Tomcat底层原理分析:7.Tomcat集群配置解析
Tomcat底层原理分析:8.Tomcat安全性配置解析
Tomcat底层原理分析:9.Tomcat性能调优
【本文导读】
本文主要讲了从三个方面对Tomcat进行优化:
1.Tomcat的JVM的内存优化
2.Tomcat的JVM的GC策略优化
3.Tomcat的连接器优化
1.JVM调优
Tomcat的实质也是一个Java应用,那么JVM的配置就与其运行性能密切相关。通常,JVM优化的重点则集中在内存分配和GC策略的调整上,原因如下:
- 内存直接影响服务的运行效率和吞吐量;
- JVM的GC机制会不同程度地导致程序运行中断(即JVM执行垃圾回收时,程序会停止运行),根据应用程序的特点,选择不同的GC策略,可以极大地减少GC次数,提示GC效率,从而改善程序运行性能。
1.1内存调优
1.1.1参数详解
参数 | 含义 |
---|---|
-server | 启动Server,以服务端模式运行,服务端模式:启动速度慢,启动后响应速度快 |
-Xms | 堆内存的初始大小 |
-Xmx | 堆内存的最大大小 |
-Xmn | 新生代的内存大小,官方建议是整个堆的3/8 |
-XX:MetaspaceSize | 元空间内存的初始大小,在JDK1.8版本之前配置为:-XX:PermSize(永久代/持久代) |
-XX:MaxMetaspaceSize | 元空间内存的最大大小,在JDK1.8版本之前配置为:-XX:PermSize(永久代/持久代) |
-XX:InitialCodeCacheSize -XX:ReservedCodeCacheSize | 代码缓存区大小 |
-XX:MaxNewSize | 新生代最大内存 |
-XX:NewRatio | 设置新生代和老年代的比例。好处:新生代的大小可以随着整个堆的大小动态扩展,如-XX:NewRatio=3,则老年代占堆大小的3/4,新生代占堆大小的1/4 |
-XX:SurvivorRatio | 设置伊甸园区(Eden)与幸存区的比例。如-XX:SurvivorRatio=8,则伊甸园区(Eden)的大小是幸存区的8倍,则伊甸园区(Eden)占新生代大小的8/10,幸存区From占1/10,幸存区To占1/10。注意,两个幸存区永远一样大。 |
1.1.2调优
参数 | 优化建议 | 原因 |
---|---|---|
-server | 建议开启 | 服务端模式:启动速度慢,启动后响应速度快 |
-Xms | 建议与-Xmx设置相同 | 避免Tomcat运行期间内对内存进行重新分配,造成资源浪费 |
-Xmx | 建议设置成可用内存的80% | |
-Xmn | 官方建议是整个堆的3/8 | |
-XX:MetaspaceSize | 无 | |
-XX:MaxMetaspaceSize | 建议使用默认值,默认无限大 | |
-XX:InitialCodeCacheSize -XX:ReservedCodeCacheSize | 无 | |
-XX:MaxNewSize | 建议使用默认值,默认16M | |
-XX:NewRatio | 建议使用默认值,默认为2 | |
-XX:SurvivorRatio | 建议使用默认值,默认为8 |
1.2GC调优
JVM的GC机制的性能主要有以下两个指标:
- 吞吐量:工作时间(不包括GC时间)占总时间的百分比,工作时间不仅仅是程序运行时间,还包括内存分配时间;
- 暂停时间:测试时间段内,“由GC机制导致的应用程序停止响应的次数”/“时间”的比率
1.2.1各种垃圾收集器的对比
垃圾收集器 | 缺点 | 优点 | 适应场景 |
---|---|---|---|
Serial (串行收集器) | 单线程收集器,在执行垃圾收集时会使所有的用户线程暂停,即系统出现卡顿 | 因为它是单线程执行,在单核或者核数比较少的处理器环境中它没有线程切换的开销,专心做垃圾回收,可以获得最高的收集效率。 | 桌面应用和近几年流行起来的部分微服务中,分配给虚拟机管理的内存非常小,收集一两百兆的新生代只需要几十毫秒,最多一百毫秒,只要是频率不高,用户可以说是无感知,这类场景下还是一个非常好的选择。 |
Parallel (并行收集器) | 仍然会使所有的用户线程暂停,即系统出现卡顿 | 以并行的方式执行新生代的垃圾回收,显著降低垃圾回收的开销 | 适用于“在多核cpu或者多线程硬件上运行数据量较大的应用”,又称吞吐量收集器 |
CMS (并发标记清除收集器) | 因为用户线程和垃圾回收线程同时执行,但是不一定是并行的,有可能是交替进行,所以会降低应用程序的性能 | 以并发的方式执行大部分垃圾回收工作,缩短垃圾回收时的暂停时间 | 适用于“响应时间优先于吞吐量”并且“能负担得起与垃圾回收共享处理器资源”的应用 |
G1 (并发收集器) | 同上 | 同上 | 适用于内存容量大的多核服务器,可以在满足垃圾回收暂停时间足够小的同时,以最大的可能性实现高吞吐量(JDK1.7以后) |
1.2.2在Tomcat中配置GC策略
1.2.2.1垃圾收集器参数
参数 | 描述 |
---|---|
-XX:+UseSerialGC | 启用串行收集器 |
-XX:+UseParallelGC | 启用并行收集器,如果设置了该参数,则默认同时启用-XX:+UseParallelOldGC |
-XX:+UseParallelOldGC | FullGC采用并行收集,默认禁用 |
-XX:+UseParNewGC | 为新生代启用并行收集器,如果设置了该参数,则默认同时启用-XX:+UseConcMarkSweepGC |
-XX:+UseConcMarkSweepGC | 为老年代启用CMS垃圾收集器 当并行收集器无法满足应用的延迟需求时,推荐使用CMS或G1收集器 如果设置了该参数,则默认同时启用-XX:+UseParNewGC |
-XX:+ParallelGCThreads | 为新生代和老年代的垃圾收集器设置线程个数,默认值依赖于JVM使用的cpu个数 |
-XX:+UseG!GC | 启用G1收集器,G1是服务器类型的收集器,用于多核、大内存的机器。它在保持高吞吐量的情况下,高概率地满足“缩短暂停时间”的需求 |
1.2.2.2“打印垃圾收集器信息”参数
参数 | 描述 |
---|---|
-XX:+PrintGC | 打印每次GC的信息 |
-XX:+PrintGCApplicationConcurrentTime | 打印最后一次暂停之后所经过的时间,即响应并发执行的时间 |
-XX:+PrintGCApplicationStoppedTime | 打印GC时应用暂停时间 |
-XX:+PrintGCDateStamps | 打印每次GC的时间戳 |
-XX:+PrintGCDetails | 打印每次GC的详细信息 |
-XX:+PrintGCTaskTimeStamps | 打印每次GC工作线程任务的时间戳 |
-XX:+PrintGCTimeStamps | 打印每次GC的时间戳 |
1.2.2.3示例
# 在tomcat/bin/catalina.sh中添加以下内容
JAVA_OPTS="-XX:+UseConcMarkSweepGC -XX:+PrintGCDetails"
# 作用:为老年代启用CMS垃圾收集器,并打印每次GC的详细信息
总结:根据实际项目的情况来决定给Tomcat配置什么样的垃圾收集器,参考各垃圾收集器的适用场景
2.Tomcat配置调优(连接器)
调整Tomcat的连接器配置,可以提升应用服务器的性能
参数 | 描述 | 优化 |
---|---|---|
maxConnections | 最大连接数,超过该数值,额外请求就会阻塞,直到连接数低于该值 | 对于cpu要求较高时(计算型),建议不要配置过大;较低时,建议配置在2000左右(根据实际服务器性能来决定) |
maxThreads | 最大线程数 | 需要根据服务器硬件信息设置一个合理的值 |
acceptCount | 最大排队等待数,请求数超过最大连接数后,额外的请求会存放在任务队列中,队列容量就是该值,因此一个Tomcat的最大请求处理数量=maxConnections+acceptCount |