一、Tomcat 调优大致分为两大类:
- Tomcat 的自身调优:
- 采用动静分离节约 Tomcat 的性能
- 调整 Tomcat 的线程池
- 调整 Tomcat 的连接器
- 修改 Tomcat 的运行模式
- 禁用 AJP 连接器
- JVM的调优:
- 调优Jvm内存
二、Tomcat 自身调优
1. 采用动静分离
静态资源如果让 Tomcat 处理的话 ,Tomcat 的性能会被损耗很多。所以我们一般都是采用:Nginx+Tomcat 实现动静分离,让 Tomcat 只负责 jsp 文件的解析工作,Nginx 实现静态资源的访问。
2. 调优 Tomcat 线程池
打开 tomcat 的server.xml,配置Executor,相关参数说明如下:
<Executor
name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="150"
minSpareThreads="4"
maxIdLeTime="60000"/>
参数解释:
- name:给执行器(线程池)起一个名字
- namePrefix:指定线程池中的每一个线程的name前缀
- maxThreads:线程池中最大的线程数量
假设:请求的数量超过了“750”,这不是意味着将maxThreads属性值设置为“750”,它的最好解决方案是使用“Tomcat集群”。也就是说,如果有“1000”请求,两个Tomcat实例设置“maxThreads= 500”,而不是在单Tomcat实例的情况下设置maxThreads=1000。 - minSpareThreads:线程池中允许空闲的线程数量(多余的线程都杀死)
- maxIdLeTime:一个线程空闲多久算是一个空闲线程
详细配置建议阅读官方文档。
3. 调优 Tomcat 的连接器 Connector
打开 Tomcat 的 server.xml,(比较完整)配置 Connector,参数说明如下:
<Connector
executor = "tomcatThreadPool"
port="8081"
protocol="HTTP/1.1"
connectionTimeout="20000"
enableLookups="false"
URIEncoding="UTF-8"
redirectPort="8443"
maxThreads="600"
minSpareThreads="100"
acceptCount="700"
maxSpareThreads="500"
server="None" />
参数解释:
- executor:指定这个连接器所使用的执行器(线程池)。对应“Executor ”配置中的name值。
- enableLookups="false":关闭 DNS 解析,减少性能损耗。
- maxThreads="X" 表示最多同时处理X个连接。相当于最大线程数。
- minSpareThreads="X" 初始化X个连接。最小空闲线程数,这里是一直会运行的线程。
- acceptCount="X" 当同时连接的人数达到maxThreads时,还可以排队,队列大小为X。超过X就不处理。
- maxSpareThreads="X" 表示如果最多可以有X个线程,一旦超过X个,则会关闭不再需要的线程。
- minProcessors:服务器启动时创建的最少线程数;
- maxProcessors:最大可以创建的线程数;
注意:
与压缩有关系的配置:如果已经对代码进行了动静分离,静态页面和图片等数据就不需要 Tomcat 处理了,那么也就不需要在 Tomcat 中配置压缩了;
4. 通过修改 Tomcat 的运行模式
同步阻塞IO(JAVA BIO)
Tomcat8 以下版本,默认使用的就是 BIO模式。服务器实现模式为一个连接一个线程(one connection one thread),对于每一个请求都要创建一个线程来进行处理,不适合高并发。当然可以通过线程池机制改善。
JAVA NIO
又分为同步非阻塞IO,异步阻塞IO。与BIO最大的区别one request one thread.可以复用同一个线程处理多个connection(多路复用)。Tomcat8 以上版本,默认使用的就是NIO模式「非阻塞式 IO」。
异步非阻塞IO(Java NIO2又叫AIO)
与NIO的区别主要是操作系统的底层区别。可以做个比喻:比作快递,NIO就是网购后要自己到官网查下快递是否已经到了(可能是多次),然后自己去取快递;AIO就是快递员送货上门了(不用关注快递进度)。
适用:
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
在server.xml中
<Connector
executor = "tomcatThreadPool"
port="8081"
protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
enableLookups="false" />
实现对Tomcat的IO切换。
APR(Apache Portable Runtime)
APR是一个高可移植库。它是Apache HTTP Server 2.x的核心,能更好地和其它本地web技术集成,总体上让Java更有效率作为一个高性能web服务器平台而不是简单作为后台容器。是Tomcat生产环境运行的首选方式,如果操作系统未安装 APR 或者 APR 路径未指到 Tomcat 默认可识别的路径,则 APR 模式无法启动,自动切换启动 NIO 模式。所以必须要安装Apache Tomcat Native Library,直接启动就支持 APR,APR是从操作系统级别解决异步 IO 问题,排除代码问题Tomcat优化到这个层次,可以大幅度的提高性能。APR 的本质就是使用 JNI 技术调用操作系统底层的 IO 接口,所以需要提前安装所需要的依赖。
在产品环境中,特别是直接使用Tomcat做WEB服务器的时候,应该使用Tomcat Native来提高其性能。如果不配APR,基本上300个线程很快就会用满,以后的请求就只好等待。但是配上APR之后,并发的线程数量明显下降,从原来的300可能会马上下降到只有几十,新的请求会毫无阻塞的进来。
在局域网环境测,就算是400个并发,也是一瞬间就处理/传输完毕,但是在真实的Internet环境下,页面处理时间只占0.1%都不到,绝大部分时间都用来页面传输。如果不用APR,一个线程同一时间只能处理一个用户,势必会造成阻塞。所以生产环境下用APR是非常必要的。
5. 禁用 AJP 连接器
AJP的全称 Apache JServer Protocol。使用 Nginx+Tomcat的架构,所以用不着 AJP 协议,所以把AJP连接器禁用。
- Linux 下修改 TOMCAT_HOME/bin/catalina.sh,在其中加入如下代码,可以放在 CLASSPATH = 下面:
JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m"
- windows 下修改 TOMCAT_HOME/bin/catalina.bat,在其中加入如下代码,可以放在 set CLASSPATH = 下面:
set JAVA_OPTS=-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m
参数说明:
- -server:启用 JDK的 server 版本;
- -Xms:Java虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能;
- -Xmx:Java虚拟机可使用堆的最大内存;
- -XX:PermSize:Java虚拟机永久代大小;
- -XX:MaxPermSize:Java虚拟机永久代大小最大值;
三、JVM 调优
Tomcat 是运行在 JVM 上的,所以对 JVM 的调优也是非常有必要的。启动时告诉JVM我要一块大内存,调优内存是最直接的方式。调整堆大小的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。找到 catalina.sh:
catalina.sh.jpg添加:
JAVA_OPTS='-Xms256m -Xmx512m'
完整参数设置:
JAVA_OPTS="-Djava.awt.headless=true
-Dfile.encoding=UTF-8-server
-Xms1024m
-Xmx1024m
-XX:NewSize=512m
-XX:MaxNewSize=512m
-XXermSize=512m
-XX:MaxPermSize=512m
-XX:+DisableExplicitGC"
- -Xms<size> Java虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能;
-
-Xmx<size> Java虚拟机可使用堆的最大内存。实际参数大小根据服务器配置或者项目具体设置。
赞赞赞.gif
网友评论