Tomcat主要的调优配置,主要集中于
Connector(连接器)的调优了,偶尔也会配置Excecutor的调优
Tomcat 9.0 有三类 Connector
- Http/1.1(Http Connector)
- Http/2(Http2 Upgrade Protocol(Tomcat 8.5引入)
- AJP(AJP Connector)
工作流程:
- 每个请求都需要一个线程去处理
- 如果接收到的并发请求>当前处理请求线程所能处理的数量,则创建其他线程去处理,直到达到maxThreads为止
- 如果线程数达到maxThreads设置的值后,依然接收到更多的请求,那么请求将会堆积在Connector创建的server sockert中(即accpet队列),直到达到acceptCount的值位置.如果堆积的请求数目达到acceptCount后,依然受到更多的请求,那么直接返回connection refused
常见属性
- 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端整数标为,如果设置为-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,生产环境建议保持关闭。
- commpression::是否开启 GZIP 压缩。取值 off(禁用)、on(打开,压缩文本数据),force(强制压缩所有格式)、数字(表示数据量达到该值就 GZIP 传输)。
- connectionUploadTimeout:connectionUploadTimeout:指定上传时的超时。disableUploadTimeout 需设置成 false 才有效
- redirectPort:表示安全通信(https)转发端口
- executor:指定 executor 名称。如果设置了此属性,则 Connector 将使用该 Executor 执行程序。如果不设置 executor 属性,则 Connector 将使用内部私有的 Executor 来提供线程池。该属性主要用来实现在多个 Connector 及其他组件之间共享线程池。
Executor常用属性
定义线程池,从而在多个 Connector (主要) 及其他组件之间共享。Executor 必须实现 org.apache.catalina.Executor 接口。
参数名 | 参数介绍 |
---|---|
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 不会关闭) |
prestartminSpareThreads | :在启动 Executor 时是否就启动 minSpareThreads 个线程,默认 false |
threadRenewalDelay | 如果配置了 ThreadLocalLeakPreventionListener,它将会通知 Executor 有关上下文停止的信息。一旦上下文停止后,线程池中的线程将会被更新。为了避免同时更新线程,可用此属性设置更新的延迟。默认 1000,单位毫秒,如果设成负数,则线程不会被更新。 |
maxQueueSize | 拒绝执行之前可以排队等待执行的任务数量,默认 Integer.MAX_VALUE |
Spring Boot项目支持的调优参数
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"
为Session设置合理的超时
Spring Boot项目下
server.servlet.session.timeout:30m
Q.E.D.