Tomcat架构以及性能调优

之前面试被问到过tomcat调优的问题,一直想着梳理一下这块的知识。最近查阅了一些资料,在这里汇总一下。如果大佬们发现有不对的地方,还请指正,谢谢。
tomcat容器是一个轻型的应用服务器。专业的说法是JSP/Servlet容器。tomcat可以处理Html静态资源以及JSP/Servlet动态资源。

tomcat的架构图如下:
tomcat架构图
简单理解如下:

tomcat核心架构图
架构图就是按照tomcat的核心配置文件server.xml进行分析汇总的。
下面简单讲解一下各个元素的作用。
顶层元素是一个Server元素,Server元素中默认带着两个属性
1 .Server
tomcat的顶层server元素
port代表tomcat服务接收停止服务的端口
shutdown代表当接收到shutdown字符串时即关闭tomcat服务。

2 .Service
Service元素描述
Service自身不是一个容器,它是一个包含若干Connector,和一个Engine的集合。
Engine处理所有Connector收到的所有请求。

Service可以定义多个,如下:


name为Catalina,Catalina是tomcat的小名,用来处理tomcat接收到的web请求
name为Apache用来处理Apache服务器转发过来的web请求

3 .Connector
Connector元素描述
Connector,顾名思义是连接器,此模块负责监听来自客户端的请求
调优的重点就在Connector模块。该元素可以配置多个。接收到的请求交给Engine元素
port:接收请求的端口
protocol:Connector使用的协议,目前可选值为3个。

BIO(同步阻塞模式。tomcat7以下默认)
NIO(异步非阻塞模式。tomcat8以上默认)
APR(Apache可移植运行时)配置比较复杂,需要安装APR库以及其他一些依赖库。但是对于高并发的处理性能最好

4 .Engine
在这里插入图片描述
Engine元素负责处理Connector传递下来的请求。
name属性是Engine的逻辑名称,在日志和错误信息中会使用到
defaultHost属性是默认主机,主机的概念,下面会提到。默认主机是如果所有的Host都不能匹配到,就会使用默认主机处理请求。

5 .Host
在这里插入图片描述
Host为虚拟主机。虚拟主机可以运行多个项目,我们的项目需要依赖虚拟主机才可以运行。就好比,java程序想要运行,需要依赖JVM类似。
name属性是虚拟主机的名称
appBase是项目部署的路径,默认是webapps路径。此处可以配置项目的绝对路径
unpackWARs是war包需要解压之后运行。如果改为false,则直接运行war包
autoDeploy是指自动部署
6 .Context
Context是Host容器中的一个子容器。我们标准的Server.xml配置文件中并没有这个元素。
该元素指的就是实际的项目,也就是Servlet。

7 .GlobalNamingResources
在这里插入图片描述
可以把它理解成“全局资源”;Engine元素中的Realm元素会使用全局资源的配置。提供了一种用户密码与web应用的映射关系,从而达到角色安全管理的作用。不做研究。
以上就是Tomcat的架构

下面说一下Tomcat的调优
调优工作主要从以下几个方面进行
1 .tomcat启动模式
2 .Tomcat连接池
3 .禁用AJP协议
4 .调节Tomcat的Jvm参数

tomcat的启动模式一共有三种
1 .BIO(同步阻塞模式。tomcat7以下默认)
如何配置:
找到对应的Connector元素 (Connector元素可以有多个)
将protocal属性改为:
org.apache.coyote.http11.Http11Protocol
在这里插入图片描述
然后启动tomcat应用服务器
在日志的末尾,可以看到如下日志
在这里插入图片描述
此时说明,启动模式已经改为了bio模式。
2 .NIO(异步非阻塞模式。tomcat8以上默认)
如何配置
找到对应的Connector元素 (Connector元素可以有多个)
将protocal属性改为:
org.apache.coyote.http11.Http11NioProtocol
在这里插入图片描述
然后启动tomcat应用服务器
在日志的末尾,可以看到如下日志:
在这里插入图片描述
此时说明,启动模式已经改为了nio模式。
3 .APR(Apache可移植运行时)配置比较复杂,需要安装APR库以及其他一些依赖库。但是对于高并发的处理性能最好
这种的配置有点复杂,需要装一堆依赖,感兴趣的自行百度吧。我就偷懒了。。。

tomcat的线程池技术
tomcat线程池工作原理简要介绍:
如果我们开启了minSpareThreads参数以及prestartminSpareThread参数。(两个参数的介绍见下文)此时,tomcat启动就会创建一部分线程,预热线程池,然后当并发请求数高于minSpareThreads参数时,tomcat就开始创建线程(注意这个地方和jdk原生的线程池是不一样的。jdk原生的线程池,如果请求数量高于核心线程,会将多余的请求放入队列,但是tomcat不能这么做。原因是:tomcat要保证请求的响应时间,所以只要能建线程就不放队列),当请求数多于maxThreads时,此时才会放入队列(tomcat队列的默认长度是Integer.MAX_VALUE,这点要注意),如果队列长度自定义了,当队列也满了,此时线程池执行拒绝策略,但是tomcat自己会catch住拒绝异常,然后重新尝试放入队列。当线程池不繁忙,线程的空闲时间超过了maxIdleTime时,Tomcat线程池就开始销毁线程,直到线程池线程数量达到minSapreThreas的数量才停止销毁。

此时,如何可以提高最大线程数呢?
可以使用tomcat的线程池
tomcat的线程池在Server.xml中的体现是元素。也就是执行器
在这里插入图片描述
从官方的注释中可以看出,连接池可以定义多个,通过name属性进行区分。
在这里,我们就可以改变tomcat的最大线程。改为150
然后Connector元素通过属性executor引用这个连接池即可。注意:Executor标签要配置在Connector元素之前,以便Connector元素引用。一旦在Connector中配置了executor元素,在Connector中的线程相关属性设置将会被忽略
在这里插入图片描述
Executor元素中有很多可选属性,我简单列举一些常用的属性
maxThreads:最大线程数。经验值范围为200-800。可以从400设置起再进行调优。这个一定要参考自己的机器性能,我之前有一台物理机,64G内存,16CPU,8核,可以使用lscpu命令查看具体的cpu信息。maxThreads可以直接设置到1600。jemter1500并发,报错率控制在了0.33%,相当优秀。但是要注意:不要以为自己机器内存很大,我就可以无限创建线程。线程数过多,线程上下文切换也会非常的频繁,导致cpu打满,cpu满了,请求就会无限的等待,直到超时报错。查看上下文切换次数的命令。
vmstat :监控系统上下文切换
在这里插入图片描述
那个cs就是上下文切换的次数。如果可以看到,最大5万多
pidstat -w -l -p pid。监控某个应用的上下文切换
一般,上下文切换大概在几万。高的时候可能会达到几十万
我们配置此参数时,可以使用top命令查看一下cpu的使用情况,先按top,然后按数字1,就可以查看每一个物理cpu的使用情况。压测时,使用率越高越好,得出一个maxThreads的临界值,然后根据此值调整业务
minSpareThreads:此项属性开启,tomcat会在启动时预先创建一些线程。默认值为10。此项功能,可以预防流量突然激增。
prestartminSpareThreads:当我们设置了minSpareThreads时,要注意开启这个值。此值默认为false。此值如果不手动设置为true,minSpareThreads的值不会生效。
maxQueueSize:线程池队列的长度。默认值为Integer.MAX_VALUE,当请求数超过maxThreads时,请求就开始放入队列。此处要注意,如果任务处理时间过长,不能使用默认值。否则会导致很多请求报超时错误
maxIdleTime:当线程数多于minSpareThreads且线程空闲时。等待maxIdleTime时间,然后线程就开始销毁,一直销毁到线程的数量等于minSpareThreads停止。

以上线程池相关参数配置在Executor元素中,下面的参数配置在Connector元素中

protocol:tomcat启动模式。三种选择:
org.apache.coyote.http11.Http11Protocol:bio
org.apache.coyote.http11.Http11NioProtocol:nio
org.apache.coyote.http11.Http11AprProtocol:apr
这个参数的默认值是HTTP/1.1,这个默认值采取的启动策略为:
当本地有apr依赖库,就启用apr模式。没有就启用bio模式
executor:connector引用线程池,一旦待引用线程池存在。connector中配置的线程相关的属性将失效(maxThreads,minSpareThreads,prestartminSpareThreads,maxQueueSize等参数)
acceptCount:经验值的范围为50-300(默认值100)当请求数超过tomcat的最大线程数后,tomcat允许进入请求队列的请求数。就是说,当请求超过200之后,tomcat允许继续访问acceptCount个数量的请求,放进队列等待。超过acceptCount数量后,后来的请求返回Connection refused错误
maxConnections:(bio模式下和maxThreads一致,nio:10000,apr:8192。它的意思是:最大连接数。设置为-1,代表不限制连接数
maxConnections+acceptCount = tomcat能接收的请求数
超过maxConnections+acceptCount的和时,tomcat就会返回Connection refused错误。
关于maxConnections,acceptCount,maxThreads,看到过一个很形象的举例。假想我们现在有一个餐厅,maxThreads就是厨师的数量,maxConnections就是餐厅的座位数,acceptCount就是排号的数量。首先maxConnections个数量的人可以直接进入餐厅就坐,等待厨师服务。超过maxConnections个数量的人,就开始从acceptCount队列中取号排号,当acceptCount队列中的号取完了,就开始拒绝再接待客人。
connectionTimeout:经验值为2000-60000(默认值60000ms)当tomcat接受了连接,但是不能即时处理,会等待connectionTimeout时间。超过此时间,就返回客户端超时错误。此值单位为毫秒。如果设置为-1,将不限制超时
maxHttpHeaderSize:HTTP请求和响应头的最大容量,以字节为单位,默认值为4096字节
tcpNoDelay:默认值为true。如果为true,TCP_NO_DELAY选项将被设置为服务器上的套接字上,在大多数情况下,这样做可以提高性能。
compression:连接器可以使用HTTP/1.1 GZIP压缩。可接受的参数是 “off”(禁用压缩)on(开启压缩,这将导致文本数据被压缩)force(强制在所有情况下压缩),或者是一个整数值(这是相当于on,但是设定了最小的数据压缩值,超过此值才会被压缩)
compressionMinSize:最小的数据压缩值。超过此值,文本数据才会被压缩。
disableUploadTimeout:禁用上传超时时间。上传时间没有超时。
connectionUploadTimeout:上传超时时间。单位毫秒。只有disableUploadTimeout设置为false时有效。
redirectPort:ssl协议转发端口。tomcat在接收http请求时,如果这时过来有个ssl的安全请求,会转发到8443端口。
enableLookups:调用request.getRemoteHost()执行DNS查询,以返回远程主机的主机名,如果设置为false,则直接返回IP地址。
URIEncoding:tomcat服务端编码。一般都是" UTF-8 "
SSLEnabled:开启SSL加密传输。默认为false;

我们可以根据自己项目的实际情况去灵活的调整这些参数。
调整完之后,我们可以访问tomcat的欢迎页,点击status标签,查看修改的参数值。进入status,需要输入tomcat的用户名/密码
通过配置conf / tomcat-user.xml文件,加入以下元素
在这里插入图片描述
然后访问Tomcat的欢迎页
点击页面中的status,即可进入Tomcat的管理页面

禁用AJP协议
AJP协议是tomcat专门用来处理html静态文件的协议。如果我们网站采用的是nginx+tomcat的架构方式,那AJP协议就完全多余了。静态文件的访问,通过nginx完全就可以实现。AJP相对nginx来说,就复杂一点了,效率肯定没有nginx高。所以说,我们可以直接禁用AJP协议。
禁用的方法也很简单。找到如下配置,直接全部注释掉就好了。
在这里插入图片描述
提高tomcat的jvm内存参数
这个优化,对于tomcat的性能提高有很明显的变化。

linux系统配置方法:
进入tomcat的bin目录
编辑catalina.sh文件,将以上参数添加到catalina.sh文件的除注释外的第一行;
JAVA_OPTS="-server -Xms4096m -Xmx4096m -Dfile.encoding=UTF-8 -XX:PermSize=512M -XX:MaxPermSize=512m -Djava.awt.headless=true"
将以上参数添加到,catalina.sh文件的除注释外的第一行

windows系统配置方法:
Set JAVA_OPTS=-server -Xms2048m -Xmx2048m -Dfile.encoding=UTF-8 -XX:PermSize=256m -XX:MaxPermSize=600m -Djava.awt.headless=true
配置位置:
catalina.bat脚本中的116行和117行之间:
在这里插入图片描述

配置注意事项:
不要把MaxPermSize设置的太大,一般在600m即可;

Xms:堆最小内存
Xmx:堆最大内存
Dfile.encoding:服务端编码
PermSize:非堆内存容量
MaxPermSize:非堆内存最大容量
Djava.awt.headless:支持在linux上,利用java作图形处理 (图片缩放,生成报表)

以上就是本次学习tomcat调优的一些总结。期间查阅了很多的资料,看了很多的帖子。这里就不一一列举了,感谢各位的分享。谢谢!
发现有任何的问题,欢迎留言交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值