JVM之Tomcat的优化

Tomcat8优化

tomcat服务器在JavaEE项目中使用率非常高,所以在生产环境对tomcat的优化也变得非 常重要了。
对于tomcat的优化,主要是从2个方面入手,一是,tomcat自身的配置,另一个是 tomcat所运行的jvm虚拟机的调优。
下面我们将从这2个方面进行讲解。

Tomcat配置优化

部署安装tomcat8

下载并安装:https://tomcat.apache.org/download-80.cgi
在这里插入图片描述

cd /tmp 
wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat‐ 8/v8.5.34/bin/apache‐tomcat‐8.5.34.tar.gz 

tar ‐xvf apache‐tomcat‐8.5.34.tar.gz 
cd apache‐tomcat‐8.5.34/conf 
#修改配置文件,配置tomcat的管理用户 
vim tomcat‐users.xml 
#写入如下内容: 
<role rolename="manager"/> 
<role rolename="manager-gui"/> 
<role rolename="admin"/> 
<role rolename="admin-gui"/> 
<user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/> 
#保存退出

#如果是tomcat7,配置了tomcat用户就可以登录系统了,但是tomcat8中不行,还需要修改 另一个配置文件,否则访问不了,提示403 
vim webapps/manager/META‐INF/context.xml 

#将<Valve的内容注释掉 
<Context antiResourceLocking="false" privileged="true" > 
 <!‐‐ <Valve className="org.apache.catalina.valves.RemoteAddrValve" 
  	allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> ‐‐> 
  	<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.Cs rfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/> </Context> 
#保存退出即可 

#启动tomcat 
cd /tmp/apache‐tomcat‐8.5.34/bin/ 
./startup.sh && tail ‐f ../logs/catalina.out 

#打开浏览器进行测试访问 
http://192.168.40.133:8080/

在这里插入图片描述
点击“Server Status”,输入用户名、密码进行登录,tomcat/tomcat
在这里插入图片描述
在这里插入图片描述
进去之后即可看到服务的信息。

禁用AJP连接

在服务状态页面中可以看到,默认状态下会启用AJP服务,并且占用8009端口。
在这里插入图片描述
什么是AJP呢?
AJP(Apache JServer Protocol)
AJPv13协议是面向包的。WEB服务器和Servlet容器通过TCP连接来交互;为了节省 SOCKET创建的昂贵代价,WEB服务器会尝试维护一个永久TCP连接到servlet容器,并且 在多个请求和响应周期过程会重用连接。
在这里插入图片描述
我们一般是使用Nginx+tomcat的架构,所以用不着AJP协议,所以把AJP连接器禁用。
修改conf下的server.xml文件,将AJP服务禁用即可。

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

在这里插入图片描述
重启tomcat,查看效果。
在这里插入图片描述
可以看到AJP服务已经不在了。

执行器(线程池)

在tomcat中每一个用户请求都是一个线程,所以可以使用线程池提高性能。
修改server.xml文件:

<!‐‐将注释打开‐‐> 
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" 
	maxThreads="500" minSpareThreads="50" 
	prestartminSpareThreads="true" maxQueueSize="100"/> 
<!‐‐ 
参数说明: 
maxThreads:最大并发数,默认设置 200,一般建议在 500 ~ 1000,根据硬件设施和业 务来判断
minSpareThreads:Tomcat 初始化时创建的线程数,默认设置 25 
prestartminSpareThreads: 在 Tomcat 初始化的时候就初始化 minSpareThreads 的 参数值,如果不等于 true,minSpareThreads 的值就没啥效果了 
maxQueueSize,最大的等待队列数,超过则拒绝请求 
‐‐> 
<!‐‐在Connector中设置executor属性指向上面的执行器‐‐> 
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" 
			connectionTimeout="20000" 
			redirectPort="8443" />

保存退出,重启tomcat,查看效果。
在这里插入图片描述
在页面中显示最大线程数为-1,这个是正常的,仅仅是显示的问题,实际使用的指定的 值。
也有人遇到这样的问题:https://blog.csdn.net/weixin_38278878/article/details/80144397

3种运行模式

tomcat的运行模式有3种:

  1. bio
    默认的模式,性能非常低下,没有经过任何优化处理和支持.
  2. nio nio
    (new I/O),是Java SE 1.4及后续版本提供的一种新的I/O操作方式(即java.nio包及 其子包)。Java nio是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,因此nio 也被看成是non-blocking I/O的缩写。它拥有比传统I/O操作(bio)更好的并发运行性 能。
  3. apr
    安装起来最困难,但是从操作系统级别来解决异步的IO问题,大幅度的提高性能.

推荐使用nio,不过,在tomcat8中有最新的nio2,速度更快,建议使用nio2.
设置nio2

<Connector executor="tomcatThreadPool" port="8080"
protocol="org.apache.coyote.http11.Http11Nio2Protocol" 
		connectionTimeout="20000" 
		redirectPort="8443" />

在这里插入图片描述

可以看到已经设置为nio2了。

部署测试用的Java web项目

为了方便测试性能,我们将部署一个java web项目,这个项目本身和本套课程没有什么 关系,仅仅用于测试。

注意:这里在测试时,我们使用一个新的tomcat,进行测试,后面再对其进行优化 调整,再测试。

创建dashboard数据库

在资料中找到到sql脚本文件dashboard.sql,在linux服务器上执行。

cat dashboard.sql | mysql ‐uroot ‐proot

创建完成后,可以看到有3张表。
在这里插入图片描述

部署web应用

在资料中找到itcat-dashboard-web.war,上传到linux服务器,进行部署安装。

cd /tmp/apache‐tomcat‐8.5.34/webapps 
rm ‐rf * 
mkdir ROOT 
cd ROOT/ 

rz上传war包 
jar ‐xvf itcat‐dashboard‐web.war 
rm ‐rf itcat‐dashboard‐web.war 

#修改数据库配置文件 
cd /tmp/apache‐tomcat‐8.5.34/webapps/ROOT/WEB‐INF/classes 
vim jdbc.properties 

#这里根据自己的实际情况进行配置 
jdbc.driverClassName=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://node01:3306/dashboard? 
useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true 
jdbc.username=root 

jdbc.password=root

重新启动tomcat。
访问首页,查看是否已经启动成功:http://192.168.40.133:8080/index
在这里插入图片描述

使用Apache JMeter进行测试

Apache Jmeter是开源的压力测试工具,我们借助于此工具进行测试,将测试出tomcat 的吞吐量等信息。

下载安装

下载地址:http://jmeter.apache.org/download_jmeter.cgi
在这里插入图片描述
安装:直接将下载好的Zip压缩包进行解压即可。
在这里插入图片描述
进入bin目录,找到jmeter.bat文件,双击打开即可启动。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

修改主题和语言

默认的主题是黑色风格的主题并且语言是英语,这样不太方便使用,所以需要修改下主题和中文语言。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
主题修改完成。
接下来设置语言为简体中文。
在这里插入图片描述
语言修改完成。
在这里插入图片描述

创建首页的测试用例

第一步:保存测试用例
在这里插入图片描述
第二步:添加线程组,使用线程模拟用户的并发。
在这里插入图片描述
在这里插入图片描述
1000个线程,每个线程循环10次,也就是tomcat会接收到10000个请求。
第三步:添加http请求
在这里插入图片描述
在这里插入图片描述
第四步:添加请求监控
在这里插入图片描述
在这里插入图片描述

启动、进行测试

在这里插入图片描述

聚合报告

在聚合报告中,重点看吞吐量。
在这里插入图片描述

调整tomcat参数进行优化

通过上面测试可以看出,tomcat在不做任何调整时,吞吐量为73次/秒。

禁用AJP服务

在这里插入图片描述
在这里插入图片描述
可以看到,禁用AJP服务后,吞吐量会有所提升。
当然了,测试不一定准确,需要多测试几次才能看出是否有提升。

设置线程池

通过设置线程池,调整线程池相关的参数进行测试tomcat的性能。

最大线程数为500初始为50
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" 
		maxThreads="500" minSpareThreads="50" 
	prestartminSpareThreads="true"/> 

测试结果:
在这里插入图片描述

最大线程数为1000,初始为200
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" 
	maxThreads="1000" minSpareThreads="200" 
prestartminSpareThreads="true"/>

在这里插入图片描述
吞吐量为151,性能有所提升。

最大线程数为5000,初始为1000

是否是线程数越多,速度越快呢?我们来测试下。

<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" 
	maxThreads="5000" minSpareThreads="1000" 
prestartminSpareThreads="true"/>

在这里插入图片描述
可以看到,虽然最大线程已经设置到5000,但是实际测试效果并不理想,并且平均的响 应时间也边长了,所以单纯靠提升线程数量是不能一直得到性能提升的。

设置最大等待队列数

默认情况下,请求发送到tomcat,如果tomcat正忙,那么该请求会一直等待。这样虽然 可以保证每个请求都能请求到,但是请求时间就会边长。
有些时候,我们也不一定要求请求一定等待,可以设置最大等待队列大小,如果超过就 不等待了。这样虽然有些请求是失败的,但是请求时间会虽短。
典型的应用:12306。

<!‐‐最大等待数为100‐‐> 
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐"
		maxThreads="500" minSpareThreads="100" prestartminSpareThreads="true" maxQueueSize="100"/>

在这里插入图片描述
测试结果:

  • 平均响应时间:3.1秒
    • 响应时间明显缩短
  • 错误率:49.88%
    • 错误率提升到一半,也可以理解,最大线程为500,测试的并发为1000
  • 吞吐量:238次/秒
    • 吞吐量明显提升

结论:响应时间、吞吐量这2个指标需要找到平衡才能达到更好的性能。

设置nio2的运行模式

将最大线程设置为500进行测试:

<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐"
		maxThreads="500" minSpareThreads="50" prestartminSpareThreads="true"/>
<!‐‐ 设置nio2 ‐‐> 
<Connector executor="tomcatThreadPool" port="8080"
protocol="org.apache.coyote.http11.Http11Nio2Protocol" 	
		connectionTimeout="20000" 
		redirectPort="8443" />

在这里插入图片描述
可以看到,平均响应时间有缩短,吞吐量有提升,可以得出结论:nio2的性能要高于 nio。

调整JVM参数进行优化

接下来,测试通过jvm参数进行优化,为了测试一致性,依然将最大线程数设置为500, 启用nio2运行模式。

设置并行垃圾回收器
#年轻代、老年代均使用并行收集器,初始堆内存64M,最大堆内存512M 
JAVA_OPTS="‐XX:+UseParallelGC ‐XX:+UseParallelOldGC ‐Xms64m ‐Xmx512m 
‐XX:+PrintGCDetails ‐XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps 
‐XX:+PrintHeapAtGC -Xloggc:../logs/gc.log"

在这里插入图片描述
测试结果与默认的JVM参数结果接近。(执行了2次测试,结果是第二次测试的结果)

查看GC日志文件

将gc.log文件上传到gceasy.io查看gc中是否存在问题。
问题一:
在这里插入图片描述
在报告中显示,在5次GC时,系统所消耗的时间大于用户时间,这反应出的服务器的性能 存在瓶颈,调度CPU等资源所消耗的时间要长一些。
问题二
在这里插入图片描述
可以关键指标中可以看出,吞吐量表现不错,但是gc时,线程的暂停时间稍有点长。
问题三:
在这里插入图片描述
通过GC的统计可以看出:

  • 年轻代的gc有74次,次数稍有多,说明年轻代设置的大小不合适需要调整
  • FullGC有8次,说明堆内存的大小不合适,需要调整

问题四:
在这里插入图片描述
从GC原因的可以看出,年轻代大小设置不合理,导致了多次GC。

调整年轻代大小
JAVA_OPTS="‐XX:+UseParallelGC ‐XX:+UseParallelOldGC ‐Xms128m ‐Xmx1024m 
‐XX:NewSize=64m ‐XX:MaxNewSize=256m ‐XX:+PrintGCDetails 
‐XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps ‐XX:+PrintHeapAtGC 
‐Xloggc:../logs/gc.log"

将初始堆大小设置为128m,最大为1024m
初始年轻代大小64m,年轻代最大256m
在这里插入图片描述
从测试结果来看,吞吐量以及响应时间均有所提升。
查看GC日志:
在这里插入图片描述
在这里插入图片描述
可以看到GC次数要明显减少,说明调整是有效的。

设置G1垃圾回收器
#设置了最大停顿时间100毫秒,初始堆内存128m,最大堆内存1024m 
JAVA_OPTS="‐XX:+UseG1GC ‐XX:MaxGCPauseMillis=100 ‐Xms128m ‐Xmx1024m 
‐XX:+PrintGCDetails ‐XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps 
‐XX:+PrintHeapAtGC ‐Xloggc:../logs/gc.log" 

测试结果:
在这里插入图片描述
在这里插入图片描述
可以看到,吞吐量有所提升,评价响应时间也有所缩短。

小结

通过上述的测试,可以总结出,对tomcat性能优化就是需要不断的进行调整参数,然后 测试结果,可能会调优也可能会调差,这时就需要借助于gc的可视化工具来看gc的情 况。再帮我们做出决策应该调整哪些参数

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

9.冄2.7.號

你的鼓励将是我创作的巨大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值