1.修改内存/jvm配置
调整前
JAVA_OPTS="-Xms1024m -Xmx4096m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=2048m"
调整后
JAVA_OPTS="-Xms2048m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=2048m"
参数含义:
-server:启用 JDK的 server 版本;
-Xms:Java虚拟机初始化时堆的最小内存;
-Xmx:Java虚拟机可使用堆的最大内存;
-Xss:每个线程的堆栈大小;
-XX:PermSize:Java虚拟机永久代大小;
-XX:MaxPermSize:Java虚拟机永久代大小最大值;
Xms一般与Xmx配置为相同值,这样的好处是JVM不必在运行期间再为扩展内存空间而消耗性能;
jmap -heap port 查看堆使用情况
2.server.xml
每个传入请求在该请求期间需要一个线程。如果接收到的并发请求多于当前可用请求处理线程可以处理的数量,则将创建其他线程,直到配置的最大值(maxThreads属性的值)为止。如果收到更多同时请求,则将它们堆积在由Connector创建的服务器套接字内,直到配置的最大值(acceptCount 属性的值)为止。任何进一步的同时请求都将收到“连接被拒绝”错误,直到有足够的资源来处理它们为止。
1.调整Connector
Connector 是连接器,负责接收客户的请求,以及向客户端回送响应的消息。所以 Connector 的优化是重要部分。默认情况下 Tomcat 只支持 200 线程访问,超过这个数量的连接将被等待甚至超时放弃,所以我们需要提高这方面的处理能力。
其中 port 代表服务接口;protocol 代表协议类型;connectionTimeout 代表连接超时时间,单位为毫秒;redirectPort 代表安全通信(https)转发端口,一般配置成 8443。
可以看到除了这几个基本配置外并无特殊功能,所以我们需要对 Connector 进行扩展。
其中 Connector 支持参数属性可以参考 Tomcat 官方网站(https://tomcat.apache.org/tomcat-8.0-doc/config/http.html ),这里只添加一些常用的。
调整前
<Connector port="8082" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" maxConnections="800" acceptCount="500" maxThreads="400"/>
调整后
<Connector executor="tomcatThreadPool"
port="8082"
protocol="HTTP/1.1"
connectionTimeout="30000"
redirectPort="8443"
maxThreads="340"
maxConnections="1000"
acceptCount="1000"
minSpareThreads="50"
maxSpareThreads="100"
acceptorThreadCount="8"
maxHttpHeaderSize="8192"
tcpNoDelay="true"
enableLookups="false"
URIEncoding="UTF-8" />
参数含义:
executor:对Executor元素中名称的引用。如果设置了此属性,并且命名的Executor存在,则连接器将使用该Executor,所有其他线程属性将被忽略。请注意,如果未为连接器指定共享Executor,则连接器将使用内部私有执行器来提供线程池。
maxConnections:
服务器在任何给定时刻接受和处理的最大连接数。达到此数目后,服务器将接受但不处理另一个连接。在处理的连接数降至maxConnections以下之前,该附加连接会被阻塞,降至maxConnections以下后,此时服务器将再次开始接受并处理新的连接。一旦连接达到限制,操作系统仍然可以根据acceptCount设置接受新的连接。
默认值因连接器类型而异。对于BIO,除非配置了Executor,否则默认值为maxThreads的值,在这种情况下,将使用默认值,即Executor的maxThreads值。
maxThreads:tomcat创建的用于请求处理的最大线程数,默认是200。如果Connector配置了Executor,则此属性会被忽略,超过后进入队列中
minSpareThreads:tomcat初始线程数,即最小空闲线程数。默认是10.如果设置了Executor,则该属性会被忽略。
maxSpareThreads:tomcat最大空闲线程数,超过的会被关闭
acceptCount:最大排队等待数,当服务器接收到的请求数量达到maxConnections时,后面的请求将会进入任务队列中排队,这个参数就是排队的等待的请求数,超过这个数的请求将不予处理。默认值100。
acceptorThreadCount:用于接收连接的线程数,在多cpu环境可以增加此值。默认值1(官方文档中说实际上并不需要增加此值:Increase this value on a multi CPU machine, although you would never really need more than 2)。
connectionTimeout:接受连接后,此连接将等待呈现请求URI行的毫秒数。使用值-1表示没有(即无限)超时。默认值为60000(即60秒),但请注意,Tomcat附带的标准server.xml将此值设置为20000(即20秒)。除非disableUploadTimeout设置为false,否则在读取请求正文(如果有)时也会使用此超时时间。
keepAliveTimeout:该连接器在关闭连接之前等待另一个HTTP请求的毫秒数。默认值是使用为connectionTimeout属性设置的值 。使用值-1表示没有(即无限)超时。
一台tomcat的最大请求处理数=maxConnections+acceptCount。
2.调整Executor
Executor 代表了一个线程池,可以在 Tomcat 组件之间共享。使用线程池的好处在于减少了创建销毁线程的相关消耗,而且可以提高线程的使用效率。
Executor 的配置需要在Connector之前配置,否则Connector无法读取。
<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="1000"
minSpareThreads="100"
maxIdleTime="60000"
maxQueueSize="Integer.MAX_VALUE"
prestartminSpareThreads="false"
threadPriority="5"
className="org.apache.catalina.core.StandardThreadExecutor"/>
参数含义:
name:线程池名称,用于 Connector中指定。
namePrefix:所创建的每个线程的名称前缀,一个单独的线程名称为 namePrefix+threadNumber。
maxThreads:池中最大线程数,默认200。
minSpareThreads:最小空闲线程(活跃线程数),也就是核心池线程数,默认25,这些线程不会被销毁,会一直存在。
maxIdleTime:线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为60000(1分钟),单位毫秒。
maxQueueSize:在被执行前最大请求排队数目,默认为Int的最大值。除非特殊情况,这个值不需要更改,否则会有请求不会被处理的情况发生。
prestartminSpareThreads:启动线程池时是否启动 minSpareThreads部分线程。默认值为false,即不启动。
threadPriority:线程池中线程优先级,默认值为5,值从1到10。
className:线程池实现类,未指定情况下,默认实现类为org.apache.catalina.core.StandardThreadExecutor。如果想使用自定义线程池首先需要实现 org.apache.catalina.Executor接口。
线程池配置完成后需要在 Connector 中指定:
<Connector executor="tomcatThreadPool"
...
3.添加jconsle监控
1.修改catalina.sh
在JAVA_OPTS的配置后,追加以下信息:
-Djava.rmi.server.hostname=192.168.10.94 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port="18081" -Dcom.sun.management.jmxremote.authenticate="false" -Dcom.sun.management.jmxremote.ssl="false"
hostname:服务器ip
port:自定义
然后使用本地的jconsole连接
参考: https://tomcat.apache.org/tomcat-8.5-doc/config/executor.html