Tomcat 调优教程

点击上方 IT牧场 ,选择 置顶或者星标技术干货每日送达!Tomcat 调优教程_第1张图片

TIPS

本文基于Tomcat 9.0编写,理论兼容Tomcat 8.x及更高版本。

本文来探讨Tomcat的调优。

Tomcat调优参数

主要调优参数

在做Tomcat的调优时,最重要是就是Connector(连接器)的调优了(少数情况下,也可能会配置Executor)

下面贴出一段server.xml中的配置:







一个文件中可以有多个Connector以及多个Executor。

其中:

•Connector:负责接收客户端的请求以及向客户端回送响应的消息•Executor:指定线程池,从而在多个Connector(主要)及其他组件之间共享

TIPS

对执行原理感兴趣的童鞋可以参阅下这篇文章,写得相当棒:https://blog.csdn.net/zzzgd_666/article/details/88740198[1] 。由于本文重点在于“调优”,所以就不赘述了。

Connector常用属性

Connector负责接收客户端的请求以及向客户端回送响应的消息。Tomcat 9.0有三类Connector:

•HTTP/1.1(HTTP Connector)•HTTP/2(HTTP2 Upgrade Protocol)(Tomcat 8.5引入)•AJP(AJP Connector)

但不管哪种Connector,工作过程都是类似的:

•每个请求都需要1个线程去处理•如果接收到的并发请求 > 当前处理请求的线程所能处理的数量,则创建其他线程去处理,直到达到maxThreads为止•如果线程数达到maxThreads设置的值后,依然接收到更多的请求,那么请求将会堆积在Connector创建的server socket中(即accept队列),直到达到acceptCount的值为止。如果堆积的请求数目达到acceptCount后,依然受到更多的请求,那么直接返回connection refused

常用属性如下:

TIPS

•加粗的表示Tomcat调优常用的参数•这里只列出了Connector常用属性,要想阅读完整属性,可使用如下方式:

•方式一、访问 http://tomcat.apache.org/tomcat-9.0-doc/config/http.html[2] ,将9.0修改为你的Tomcat版本即可,比如想看Tomcat 8的文档,可将9.0改为8.0;•方式二、下载Tomcat并启动,访问 /docs/config/http.html 路径即可。例如:http://localhost:8080/docs/config/http.html

minSpareThreads:始终保持运行状态的线程数,默认值10。即便超过了最大空闲时间(maxIdleTime),也不会被回收。如果配置了Executor,将忽略此属性

maxThreads:Connector创建来处理请求的最大线程数,此参数决定了可以同时处理的请求的最大数量,默认200。如果配置了Executor,将忽略此属性。超过则放入请求队列中进行排队。

maxConnections:Tomcat在任意时间接收和处理的最大连接数。当连接数达到maxConnections时,仍可基于acceptCount的配置接受连接,但并不会处理,直到Tomcat接收的连接数小于maxConnections。

默认值与Connector使用的协议有关:

•NIO的默认值是10000•APR的默认值是8192•BIO的默认值为maxThreads(如果配置了Executor,则默认值是Executor的maxThreads)•在Windows下,APR/native的maxConnections值会自动调整为设置值以下最大的1024的整数倍;如设置为2000,则最大值实际是1024。如果设置为-1,则连接数不受限制。

connectionTimeout:网络连接超时时间,单位毫秒,默认60000。设为0表示永不超时,一般不建议。除非将disableUploadTimeout设置为false,否则读取request body时也会使用该超时。

acceptCount:当最大线程数(maxThreads)被使用完时,可以放入请求队列的队列长度,默认100。一旦队列满了,就会返回connection refused。因此,如果设置过大,后面进入的请求等待时间会很长;如果设置过小,后面进入的请求立马返回connection refused。一般可设置成和maxThreads相同,但具体还需根据自己的应用实际访问峰值和平均值来权衡。

enableLookups:是否启用DNS查找功能。如果设为true,会用request.getRemoteHost()执行DNS lookup,从而返回远程客户端的主机名。设为false则跳过DNS lookup,并以字符串形式返回IP地址,从而提高性能,默认false,生产环境建议保持关闭。

compression:是否开启GZIP压缩。取值off(禁用)、on(打开,压缩文本数据),force(强制压缩所有格式)、数字(表示数据量达到该值就GZIP传输)。

8 port:指定Tomcat监听的端口

9 protocol:为Connector设置使用什么协议处理入口流量,默认值 HTTP/1.1 ,使用此值的话,对于Tomcat 8及更高版本,会自动根据当前情况,使用基于NIOConnector或基于APR的Connector;对Tomcat 7及更低版本会自动根据情况使用基于BIO的Connector或基于APR的Connector。如果不想自动切换,也可人工指定协议(从Tomcat 8开始,一般无需人工设置):

// BIO,这种模式下,使用传统的I/O操作(即java.io包及其子包),性能较差。
protocol="org.apache.coyote.http11.Http11Protocol"


// NIO,使用NIO操作(即java.nio包及其子包),比传统I/O拥有更好的并发性能
protocol="org.apache.coyote.http11.Http11NioProtocol"


// NIO2,使用NIO2操作(NIO2是JDK 7引入的特性),Tomcat 8引入
protocol="org.apache.coyote.http11.Http11Nio2Protocol"


// APR,使用APR操作。APR即Apache Portable Runtime,这是一个Apache HTTP服务器的支持库。你可以认为:此模式下,Tomcat将以JNI的形式调用 Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而提高Tomcat对静态文件的处理性能
protocol="org.apache.coyote.http11.Http11AprProtocol"

下表展示了不同Connector之间的区别:

- Java Nio Connector NIO Java Nio2 Connector NIO2 APR/native Connector APR
Classname Http11NioProtocol Http11Nio2Protocol Http11AprProtocol
Tomcat Version since 6.0.x since 8.0.x since 5.5.x
Support Polling YES YES YES
Polling Size maxConnections maxConnections maxConnections
Read Request Headers Non Blocking Non Blocking Non Blocking
Read Request Body Blocking Blocking Blocking
Write Response Headers and Body Blocking Blocking Blocking
Wait for next Request Non Blocking Non Blocking Non Blocking
SSL Support Java SSL or OpenSSL Java SSL or OpenSSL OpenSSL
SSL Handshake Non blocking Non blocking Blocking
Max Connections maxConnections maxConnections maxConnections

TIPS

表格来自 http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Connector_Comparison[3]

10 connectionUploadTimeout:指定上传时的超时。disableUploadTimeout需设置成false才有效

11 disableUploadTimeout:设置为true,上传超时使用connectionTimeout,设置成false,上传超时使用connectionUploadTimeout。默认true

12 redirectPort:表示安全通信(https)转发端口

13 executor:指定executor名称。如果设置了此属性,则Connector将使用该Executor执行程序。如果不设置executor属性,则Connector将使用内部私有的Executor来提供线程池。该属性主要用来实现在多个Connector及其他组件之间共享线程池。

TIPS

压缩带来的好处是减少带宽,但缺点在于增加了服务器的CPU开销。就笔者个人的经验,很少直接用Tomcat的GZIP功能,更多使用NGINX的GZIP。

maxConnections、maxThreads、acceptCount之间的关系

我们把Tomcat想象成是一个餐厅,请求就像是去就餐的顾客。这个餐厅非常火爆,当处理不过来的时候,就会排号。

acceptCount

可以类比为餐厅的排号处能够容纳排号的最大数量,排号的数量不是无限制的,一旦达到上限,就说已经客满(直接返回connection refused)

maxConnections:可以类比为餐厅的大堂的餐桌数量,也就是可以就餐的桌数。

•如果当前连接数尚未达到maxConnection,说明还有空闲的餐桌,直接上桌即可。•如果所有餐桌都已经坐满,但是排号人数尚未达到 acceptCount,那么就排个号,等着叫号(此时,尽管还能接受请求,但是不会处理你的请求,除非有桌子空闲了)•如果取号的人数已经达到acceptCount,则取号失败,直接拒绝服务(直接返回connection refused)

maxThreads:可以类比为厨师的个数。厨师一开始只有10个(最少minSpareThreads个),如果发现忙不过来的时候,就会增加几个厨师,一致增加到maxThreads个厨师。如果还是不够,那就只能慢慢等着上菜了。这就像是你去吃饭,有时候上一道菜都吃完了,下一道菜还没有上。只不过,在计算机的世界,厨师的数量也不能无止境地增加下去。因为线程数目只要超过CPU核心数,就会存在CPU切换的开销,线程数越多,切换开销越大,所以说maxThreads设置也不能太大。

Executor常用属性

定义线程池,从而在多个Connector(主要)及其他组件之间共享。Executor必须实现org.apache.catalina.Executor接口。

常用属性如下:

TIPS

这里只列出了Connector常用属性,,要想阅读完整属性,可使用如下方式:

•方式一、访问 http://tomcat.apache.org/tomcat-9.0-doc/config/executor.html[4] ,将9.0修改为你的Tomcat版本即可,比如想看Tomcat 8的文档,可将9.0改为8.0•方式二、下载Tomcat并启动,访问 /docs/config/executor.html 路径即可。例如:http://localhost:8080/docs/config/executor.html

className:Executor的实现类。必须实现org.apache.catalina.Executor接口。默认值为org.apache.catalina.core.StandardThreadExecutor

name:Executor名称,必填且必须唯一

threadPriority:指定线程的优先级,默认5(Thread.NORM_PRIORITY)

daemon:是否为守护线程,默认true

namePrefix:指定Executor创建的线程的名称前缀。线程名称格式为namePrefix+threadNumber

maxThreads:活动线程的最大数量,默认200

minSpareThreads:使用保持活动状态的最小线程数(空闲和活动),默认25

maxIdleTime:线程最大空闲时间,单位毫秒,默认60000(1分钟)。达到该时间后就会把该线程关闭(当然如果当前活动线程数 < minSpareThreads不会关闭)

maxQueueSize:拒绝执行之前可以排队等待执行的任务数量,默认Integer.MAX_VALUE

prestartminSpareThreads:在启动Executor时是否就启动minSpareThreads个线程,默认false

threadRenewalDelay:如果配置了ThreadLocalLeakPreventionListener,它将会通知Executor有关上下文停止的信息。一旦上下文停止后,线程池中的线程将会被更新。为了避免同时更新线程,可用此属性设置更新的延迟。默认1000,单位毫秒,如果设成负数,则线程不会被更新。

其他调优参数

Host

Host表示虚拟主机。

server.xml



这里只列出了Host的调优属性,,要想阅读完整属性,可使用如下方式:

•方式一、访问 http://tomcat.apache.org/tomcat-9.0-doc/config/host.html[5] ,将9.0修改为你的Tomcat版本即可,比如想看Tomcat 8的文档,可将9.0改为8.0•方式二、下载Tomcat并启动,访问 /docs/config/host.html 路径即可。例如:http://localhost:8080/docs/config/host.html

•autoDeploy:是否要让Tomcat周期性检查新的或更新了的Web应用程序。如果设为true,则Tomcat会定期检查appBase和xmlBase目录,并自动部署。默认true。由于autoDeploy=true时,会启用一个定时任务,如果没有“自动部署”的需求,可将其设为false。

Spring Boot/Spring Cloud项目支持的调优参数

server:
  # 等价于Connector.connectionTimeout
  connection-timeout: 60s
  tomcat:
    # 等价于Connector.acceptCount
    accept-count: 100
    # 等价于Connector.maxConnections
    max-connections: 10000
    # 等价于Connector.maxThreads
    max-threads: 200
    # 等价于Connector.minSpareThreads
    min-spare-threads: 10
  # TIPS:压缩带来的好处是减少带宽,但缺点在于增加了服务器的CPU开销。就笔者个人的经验,很少直接用Tomcat的GZIP功能,更多使用NGINX的GZIP。
  compression:
    # 是否开启GZIP,默认关闭
    enabled: false
    # 执行压缩所需的最小响应大小,默认2KB
    min-response-size: 2KB
    # 想要GZIP的格式,默认"text/html", "text/xml", "text/plain",
            "text/css", "text/javascript", "application/javascript", "application/json",
            "application/xml"
    mime-types: "text/html", "text/xml"

其他调优

Tomcat Session调优

一、JSP与Session

如果使用JSP的话,如果业务允许,考虑考虑加上以下内容:

<%@ page session="false" %>

高并发场景下,可能会导致内存溢出。

拓展阅读

一个内存溢出的问题定位过程:https://blog.csdn.net/zhangm3256/article/details/83197756[6]

二、为Session设置合理的超时

超时时间不宜过长,否则也可能会造成内存上的压力。

对于传统Tomcat项目,只需在应用的 web.xml 中添加如下内容:

  
  
        30  

对于Spring Boot项目,通过如下配置设置Session即可。

server:
  servlet:
    session:
      timeout: 30m

拓展阅读

其他设置Session超时时间的方法详见 https://www.iteye.com/blog/jiangshuiy-1843622[7]

References

[1]https://blog.csdn.net/zzzgd_666/article/details/88740198
[2]http://tomcat.apache.org/tomcat-9.0-doc/config/http.html
[3]http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Connector_Comparison
[4]http://tomcat.apache.org/tomcat-9.0-doc/config/executor.html
[5]http://tomcat.apache.org/tomcat-9.0-doc/config/host.html
[6]https://blog.csdn.net/zhangm3256/article/details/83197756
[7]https://www.iteye.com/blog/jiangshuiy-1843622

干货分享

最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!

•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术群讨论

近期热文

•LinkedBlockingQueue vs ConcurrentLinkedQueue•解读Java 8 中为并发而生的 ConcurrentHashMap•Redis性能监控指标汇总•最全的DevOps工具集合,再也不怕选型了!•微服务架构下,解决数据库跨库查询的一些思路•聊聊大厂面试官必问的 MySQL 锁机制

关注我

喜欢就点个"在看"呗^_^

你可能感兴趣的:(java,linux,nginx,数据库,分布式)