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.