Tomcat

Tomcat

八月 13, 2019

Tomcat调优

一、Tomcat简介

①工作方式选择

为了提升性能,首先就要对代码进行动静分离,让 Tomcat 只负责 jsp 文件的
解析工作。如采用 Apache 和 Tomcat 的整合方式,他们之间的连接方案有三
种选择,JK、http_proxy 和 ajp_proxy。相对于 JK 的连接方式,后两种在配
置上比较简单的,灵活性方面也一点都不逊色。但就稳定性而言不像JK 这样
久经考验,所以建议采用 JK 的连接方式。

②Connector 连接器的配置

之前文件介绍过的 Tomcat 连接器的三种方式: bio、nio 和 apr,三种方式
性能差别很大,apr 的性能最优, bio 的性能最差。而 Tomcat 7 使用的
Connector 默认就启用的 Apr 协议,但需要系统安装 Apr 库,否则就会使用
bio 方式。

③配置文件优化

配置文件优化其实就是对 server.xml 优化,可以提大大提高 Tomcat 的处理
请求的能力,下面我们来看 Tomcat 容器内的优化。
默认配置下,Tomcat 会为每个连接器创建一个绑定的线程池(最大线程数
200),服务启动时,默认创建了 5 个空闲线程随时等待用户请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Server>代表整个Servlet容器组件,是最顶层元素,可以包含一个或多个
<Service>元素
<Service>包含一个<Engine>元素以及一个或多个
<Connector>元素,这些<Connector>共享一个<Engine>
<Connector/>代表和客户程序实际交互的组件,负责接收
客户请求,以及向客户返回响应
<Engine>每个<Service>元素只能包含一个<Engine>元
素,它处理在同一个<Service>中所有<Connector>接收到的客户请求
<Host>在一个<Engine>中可以包含多个
<Host>,它代表一个虚拟主机(即一个服务器程序可以部署在多个有不同IP的
服务器主机上),它可以包含一个或多个应用
<Context>使用最频繁的元素,代
表了运行在虚拟主机上的单个web应用
</Host>
</Engine>
</Service>
</Server>

二、优化

1.隐藏HTTP头部信息

1
2
3
4
5
6
[sc_vmims@replenishment apache-tomcat-8.5.9]$ vim
conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
server="Egaga-Web"/>
<!-- 主要是 server的配置 记得nginx那里也需要配置,
尤其是响应头的nginx的server信息-->

2.Connector的配置

通过ps -Lf pid |wc -l 统计当前vmism的线程数是81,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Connector port="9905" protocol="HTTP/1.1"
minSpareThreads="15"
maxConnections="475"
maxThreads="1000"
enableLookups="false"
acceptAccount="300"
acceptCount="1000"
connectionUploadTimeout="150000"
disableUploadTimeout="false"
connectionTimeout="20000"
keepAliveTimeout="120000"

maxKeepAliveRequests="1000"
URIEncoding="UTF-8"
tcpNoDelay="ture"
server="Egaga-Web"
/>

其中和最大连接数相关的参数为maxThreads 和 acceptCount 。如果要加大
并发连接数,应同时加大这两个参数。
allowTrace:是否禁用http trace方法,默认值fales
asyncTimeout:异步请求的默认超时时间(以毫秒为单位)。 如果未指定,
则此属性设置为默认值为30000(30秒)
maxHeaderCount:容器允许的请求中的最大header数。 包含比指定限制更
多的header的请求将被拒绝。 小于0表示无限制,默认值100。
maxParameterCount:POST的最大值(以字节为单位),将由容器FORM
URL参数解析来处理。若小于0则不限制,默认为2097152(2MB)。 请注
意,FailedRequestFilter可用于拒绝超出此限制的请求。
maxPostSize:在FORM或CLIENT-CERT身份验证期间,将由容器保存/缓冲
的POST的最大大小(以字节为单位)。 对于这两种类型的身份验证,POST
将在用户进行身份验证之前进行保存/缓冲。 对于CLIENT-CERT认证,POST
在SSL握手期间进行缓冲,缓冲区在处理请求时清空。 对于FORM身份验证,
POST将被保存,同时用户被重定向到登录表单,并保留,直到用户成功认证
或与身份验证请求相关联的会话过期。 可以通过将此属性设置为-1来禁用该
限制。 将属性设置为零将在身份验证期间禁用POST数据的保存。 如果未指
定,此属性设置为4096(4kb)
acceptorThreadCount:用于接受连接的线程数。 在多CPU机器上增加此
值,尽管您绝对不会需要超过2.另外,通过大量的非保持活动连接,您也可以
增加此值。 默认值为1。
maxConnections:服务器在任何给定时间接受和处理的最大连接数。当达到
这个数字时,服务器将接受一个进一步的连接,但不会处理。这个附加连接将
被阻塞,直到正在处理的连接数降到maxConnections以下,服务器再次开始
接受并重新处理新的连接。请注意,一旦达到限制,操作系统仍然可以接受基
于acceptCount设置的连接。默认值因连接器类型而异。对于BIO,默认值是
maxThreads的值,除非使用Executor,在这种情况下,默认值将是执行器的
maxThreads值。对于NIO和NIO2,默认值为10000.对于APR / native,默认值
为8192。请注意,对于Windows上的APR / native,配置的值将减少到小于或
等于maxConnections的1024的最高倍数。这是出于性能原因。如果设置
为-1,则禁用maxConnections功能,并且不计算连接。 在服务器关闭连接之
前,可以流水线的最大HTTP请求数。 将此属性设置为1将禁用HTTP / 1.0保持
活动,以及HTTP / 1.1保持活动和流水线。 将其设置为-1将允许无限量的流水
线或保持活动的HTTP请求。 如果未指定,则此属性设置为100。

maxThreads:此连接器要创建的请求处理线程的最大数量,因此确定可以处
理的最大并发请求数。 如果未指定,则此属性设置为200.如果执行程序与此连
接器相关联,则此属性将被忽略,因为连接器将使用执行程序而不是内部线程
池执行任务。 请注意,如果配置了执行程序,则为此属性设置的任何值都将
被正确记录,但会将其(例如通过JMX)报告为-1,以表明它不被使用。
minSpareThreads :Tomcat初始化时创建的 socket 线程数
tcpNoDelay:If set to true , the TCP_NO_DELAY option will be set on the
server socket, which improves performance under most circumstances. This
is set to true by default. (对于持久连接会有用)
enableLookups :是否反查域名,取值为: true 或 false 。为了提高处理能
力,应设置为 false
redirectPort: 在需要基于安全通道的场合,把客户请求转发到基于SSL 的
redirectPort 端口
acceptAccount: 监听端口队列最大数,满了之后客户请求会被拒绝(不能小
于maxSpareThreads )
acceptCount:允许的最大连接数,应大于等于maxThreads ,默认值为 100
disableUploadTimeout:上传时是否使用超时机制。
connectionUploadTimeout:上传超时时间,毕竟文件上传可能需要消耗更
多的时间,这个根据你自己的业务需要自己调,以使Servlet有较长的时间来完
成它的执行,需要与上一个参数一起配合使用才会生效。
connectionTimeout: 连接器在接受连接后等待的请求URI行的毫秒数。 使
用值-1表示无(即无穷大)超时。 默认值为60000(即60秒),但请注意
Tomcat附带的标准server.xml将其设置为20000(即20秒)。 除非
disableUploadTimeout设置为false,否则读取请求主体(如果有的话)也将使
用此超时。
keepAliveTimeout:连接器在关闭连接之前等待另一个HTTP请求的毫秒
数。 默认值是使用为connectionTimeout属性设置的值。 使用值-1表示无(即
无穷大)超时。
maxKeepAliveRequests:表示在服务器关闭之前,该连接最大支持的请求
数。超过该请求数的连接也将被关闭,1表示禁用,-1表示不限制个数,默认
100个,一般设置在100~200之间。
URIEncoding: URL统一编码
maxThreads是指Tomcat线程池做多能起的线程数,而maxConnections则
是Tomcat一瞬间做多能够处理的并发连接数。比如maxThreads=1000,
maxConnections=800,假设某一瞬间的并发时1000,那么最终Tomcat的线程
数将会是800,即同时处理800个请求,剩余200进入队列“排队”,如果
acceptCount=100,那么有100个请求会被拒掉。 注意:根据前面所说,只是

并发那一瞬间Tomcat会起800个线程处理请求,但是稳定后,某一瞬间可能只
有很少的线程处于RUNNABLE状态,大部分线程是TIMED_WAITING,如果你
的应用处理时间够快的话。所以真正决定Tomcat最大可能达到的线程数是
maxConnections这个参数和并发数,当并发数超过这个参数则请求会排队,
这时响应的快慢就看你的程序性能了。

3.禁用Tomcat管理界面

1
2
3
4
[sc_vmims@replenishment apache-tomcat-8.5.9]$ mv
webapps/* /tmp
[sc_vmims@replenishment apache-tomcat-8.5.9]$ rm -rf
conf/Catalina/localhost/*

4.删除 tomcat-users.xml 所有用户权限

将tomcat-users标签当中的参数全部删除

conf/tomcat-users.xml

1
2
3
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
</tomcat-users>

5.Host的配置

每个Host Component都是一个容器,每个标签都表示一个virtual host,在默
认的<server.xml>中,Host的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
><Host name="localhost"
>appBase="webapps"
>unpackWARs="false"
>autoDeploy="false"
>deployXML="false"
>
>> <Valve
>> className="org.apache.catalina.valves.AccessLogValve"
>> directory="/home/sc_vmims/logs/localhost_access_log"
>> prefix="localhost_access_" suffix=".log"
>> pattern="%h %l %u %t &quot;%r&quot; %s %b"
>> />
>> <Context
>> docBase="/home/sc_vmims/project/vmims"
>> reloadable="false"
>> path="/"
>> unpackWAR="false"
>
>> </Context>
>> </Host>
>

Host标签的属性:

name:virtual host的名称
appBase:web应用程序文件存放的位置,相对路径为CATALINA_HOMEM
autoDeploy :设为true,则web.xml发生变化时,tomcat自动重新部署程
序。实现这个功能必需允许后台处理
unpackWARs:tomcat在webapps文件夹中发现war文件时,是否自动将其解

workdir:tomcat使用这个目录来放工作着的servlet和jsp(以servlet形
式),这里面的servlet都是是编译好的class文件。默认为
$CATALINA_HOME/work
backgroundProcessingDelay:单位为秒,在这个属性所定义的时间之后,
此Engine将进入后台处理。如果该值为负,则直接进入后台处理。后台处理一
般用于处理低优先级的任务。
deployOnStartup:若为true,则当这个Engine启动时,tomcat将自动部署
这个host,默认为true
deployXML: 这个属性的目的是为了提高tomcat的安全性,控制web应用程
序是否能使用META-INF/contex.xml。如果设为false,则各应用程序只能访问
$CATALINA_HOME/conf///.xml。默认值为True。

context标签的属性:

className:Context的java类,默认为
org.apache.catalina.core.StandardContext
docBase:在这个Context下运行的web应用程序的文档根目录,通常被称为
Context root。如果web应用程序是以war文件的方式部署的。
path:表示web应用程序的context路径。如果你想将这个web应用程序作为此
host的默认应用程序,使用这个值:“”;默认值为docBase,war包名,或者应
用程序Context文件名
reloadable:默认值为false。设置tocmat是否应该监视/WEB-INF/classes
和/WEB-INF/lib中的变化,如果有发生改变,则自动重新部署
unloadDelay:tomcat等待web应用程序卸载的微秒数,默认为2000

unpackWAR:默认为true。设置tomcat自动解压docBase中的war文件。
workdir:为在这个host中运行的servlet定义一个工作目录。这个host下的应
用程序可以通过javax.servlet.context.tempdir属性来活动这个目录的位置。默
认为CATALINA_HOME/work
override:指示本地的context.xml(war中的META-INF/context.xml)是否
可以覆盖全局的context.xml(CATALINA_HOME/conf/context.xml),默认
值为false
allowLinking:在像linux这种允许符号链接(symbolic link)的操作系统
中,这个选项为True则运行该文件被链接到web应用程序树之外。在windows
中,这个选项必需为false。默认值为false
antiJARLocking:使用特殊的类加载器来尽量避免JAR文件的锁定,默认为
false。
antiResourceLocking:使用特殊方法来尽量避免文件锁定,默认为false。
backgroundProcessDelay:单位为秒,在这个属性所定义的时间之后,此
Engine将进入后台处理。如果该值为负,则直接进入后台处理。后台处理一般
用于处理低优先级的任务。
catcheMaxSize:设置资源代码(resource code)的最大值,默认为10240,
单位为KB
catcheTTL:验证cache的间隔时间,单位为微秒,默认值为5000
cachingAllowed:决定静态资源(配置文件,图片等)是否可以加载进cache
中,默认为true
caseSensitive:决定tocmat是否进行大小写检查,默认为true
cookies:使用cookie来进行session管理,默认为true。如果设为false,则需
要使用url重写的方式维护session
crossContext:当使用ServletContext.getContext()方法时,允许同一个
virtual host下的程序跨Context访问,默认为false
privileged:默认值为false,大部分程序这个值设为false就可以了
processTlds:设置当Context启动时对TLD进行预处理,默认为true
swallowOutput:默认为false。设置System.out和System.error的内容是否应
该记录到日志文件中
tldNamespacheAware:设置tld的处理和验证是否是namespace-aware,默
认为false

useNaming:默认为true。给web应用程序创建一个JavaEE-JNDI兼容的
InitialContext。如果web应用程序使用数据库连接,这个选项是必需的
wrapperClass:设置一个实现了org.apache.catalina.Wrapper接口的类r来包
装servlets

6.最终优化方案

在配置文件当中,主要是对连接器Connector和Host标签进行设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<Connector port="9905" protocol="HTTP/1.1"
minSpareThreads="15"
maxConnections="475"
maxThreads="1000"
enableLookups="false"
acceptAccount="300"
acceptCount="1000"
connectionUploadTimeout="150000"
disableUploadTimeout="false"
connectionTimeout="20000"
keepAliveTimeout="120000"
maxKeepAliveRequests="1000"
URIEncoding="UTF-8"
tcpNoDelay="ture"
server="Egaga-Web"
/>
.
.
.
.
<Host name="localhost"
appBase="webapps"
unpackWARs="false"
autoDeploy="false"
deployXML="false">
<Valve
className="org.apache.catalina.valves.AccessLogValve"
directory="/home/sc_vmims/logs/localhost_access_log"
prefix="localhost_access_" suffix=".log"
pattern="%h %l %u %t &quot;%r&quot; %s %b"
/>
<Context
docBase="/home/sc_vmims/project/vmims"
reloadable="false"
path="/"
unpackWAR="false">
</Context>
</Host>