用了很久的Tomcat,没怎么看过它的优化,今天抽出时间研究了下,将内容记录下。
首先,是客户端访问tomcat的一个过程,如图所示:
图中间虚线框部分是 Apache基金下的服务器来做静态资源处理的,而这部分需要花费大量时间,当用nginx和tomcat做企业级集群的时候,需要禁用掉AJP协议。
Apache和Tomcat结合的时候:
1. Apache会拦截所有请求,将servlet和JSP(.jsp结尾)请求通过AJP交给Tomcat处理,然后再把结果拿到Apache然后返回
2. 将静态资源的访问,(类似.html/.css/.jpg等之类的结尾)自己直接处理不交给tomcat,直接返回
3. Apache和Tomcat结合之后:Tomcat的HTTP Connector永远不会被用到了,可以没有
一、准备工作:
1. 配置管理员帐户:
进入conf目录下,打开tomcat-users.xml,在首尾元素中间加入:
<role rolename="manager"/>
<role rolename="manager-gui"/>
<role rolename="admin"/>
<role rolename="admin-gui"/>
<user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/>
此时,配置的用户名和密码都是tomcat。
2. 优化方法
(1)在浏览器中输入 http://localhost:8080/,点击页面中 Server Status,可以看到默认tomcat中的JVM、HTTP、AJP协议、连接池是否启用等,可以通过修改页面上显
示的参数来优化tomcat。
(2)在server.xml中进行更加深入的配置。
二、优化
1. 禁用AJP协议
(1)通过禁用AJP协议,达到在集群的时候提高处理请求的时间。
图1
(2)启动tomcat后,不论从刚刚的管理员界面,还是从控制台上(如图1所示)都可以看出,AJP协议是开启的。
我们要做的就是要将此协议禁用,禁用方法:在server.xml中,将
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
注释掉,重新启动tomcat,可以看出控制台上已经不存在上图 黑框中所示的。
2. 将BIO通讯模式修改为NIO通讯模式
(1)tomcat通讯协议支持http1.0和1.1,tomcat默认走的是BIO通讯模式,tomcat7和tomcat8之所以默认的都是效率低下的BIO通讯模式,是因为和前面的就项目做兼容。
(2)在控制台上(如图1所示)或者管理界面都可以看到,tomcat启动的通讯模式是bio的。
(3)应用场景:tomcat集群的时候,若项目比较新,都是1.5类库之前,即JDK版本大于1.5,可将集群中每一个tomcat的启动模式设置为高并发高性能的应答模式(NIO)。
(4)配置方法:在server.xml中 ,将 <Connector connectionTimeout="20000" port="8066" protocol="HTTP/1.1" redirectPort="8448"/> 改为:
<Connector connectionTimeout="20000" port="8066" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8448"/>
其中,原来的protocol="HTTP/1.1"表示遵循http1.1协议,同时,也是一个最原始的未经优化的通信协议,
修改之后的 protocol="org.apache.coyote.http11.Http11NioProtocol" ,表示以 NIO模式启动。
3. 启用外部连接池,来满足高并发已经复用的请求
图2
maxThreads:tomcat起动的最大线程数,即同时处理的任务个数,默认值为200。将
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="300" minSpareThreads="4"/>
注释打开,并修改maxThreads的值,然后在<Connector connectionTimeout="20000" port="8066" protocol="org.apache.coyote.http11.Http11NioProtocol"/>
中加入 executor="tomcatThreadPool",即最后为:
<Connector connectionTimeout="20000" port="8066" executor="tomcatThreadPool" protocol="org.apache.coyote.http11.Http11NioProtocol"/>
根据业务场景和服务器硬件资源条件可以适当的加大线程连接池,根据第三方工具去开启并发测试来确定一个最好的连接池数。 maxThreads 是 Tomcat 所能接受最大连接数。一般设置不要超过8000以上,如果你的网站访问量非常大可能使用运行多个Tomcat实例的方法,即,在一个服务器上启动多个tomcat然后做负载均衡处理。
这里还需要注意的一点是,tomcat 和 php 不同。php可以按照cpu和内存的情况去配置连接数,上万很正常。而 java 还需要注意 jvm 的参数配置。如果不注意就会因为jvm参数过小而崩溃。
4. 优化连接器
最佳实践:
<Connector port="8066" executor="tomcatThreadPool" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
enableLookups="false"
maxPostSize="10485760"
URIEncoding="UTF-8"
useBodyEncodingForURI="true"
acceptCount="100"
acceptorThreadCount="2"
disableUploadTimeout="true"
maxConnections="10000"
SSLEnabled="false"
/>
5. 在tomcat中设置JVM参数
修改bin/catalina.bat文件设置参数(注释后第一行),增加
set JAVA_OPTS=-Dfile.encoding=UTF-8
-server
-Xms1024m
-Xmx2048m
-XX:NewSize=512m
-XX:MaxNewSize=1024m
-XX:PermSize=256m
-XX:MaxPerPermSize=356m
-XX:NewRatio=2
-XX:MaxTenuringThreshold=50
-XX:+DisableExplicitGC
-Xms:设置JVM初始内存大小(默认是物理内存的1/64)
-Xmx:设置JVM可以使用的最大内存(默认是物理内存的1/4,建议:物理内存80%)
-Xmn:设置JVM最小内存(128-256m就够了,一般不设置)
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、
-Xmx相等以避免在每次GC 后调整堆的大小。
在较大型的应用项目中,默认的内存是不够的,有可能导致系统无法运行。常见的问题是报Tomcat内存溢出错误“java.lang.OutOfMemoryError:Java heap space”,从而
导致客户端显示500错误。
-XX:PermSize :为JVM启动时Perm的内存大小
-XX:MaxPermSize :为最大可占用的Perm内存大小(默认为32M)
-XX:MaxNewSize,默认为16M
PermGen space的全称是Permanent Generationspace,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到
PermGenspace中,它和存放类实例(Instance)的Heap区域不同,GC(GarbageCollection)不会在主程序运行期对PermGenspace进行清理,所以如果你的应用中有很CLASS的
话,就很可能出现“java.lang.OutOfMemoryError:PermGen space”错误。
对于WEB项目,jvm加载类时,永久域中的对象急剧增加,从而使jvm不断调整永久域大小,为了避免调整),你可以使用更多的参数配置。如果你的WEBAPP下都用了大量的第三
方jar, 其大小超过了jvm默认的大小,那么就会产生此错误信息了。
其它参数:
-XX:NewSize :默认为2M,此值设大可调大新对象区,减少FullGC次数
-XX:NewRatio :改变新旧空间的比例,意思是新空间的尺寸是旧空间的1/8(默认为8)
-XX:SurvivorRatio :改变Eden对象空间和残存空间的尺寸比例,意思是Eden对象空间的尺寸比残存空间大survivorRatio+2倍(缺省值是10)
-XX:userParNewGC 可用来设置并行收集【多CPU】
-XX:ParallelGCThreads 可用来增加并行度【多CPU】
-XXUseParallelGC 设置后可以使用并行清除收集器【多CPU】
6、压错传输
tomcat作为一个应用服务器,也是支持 gzip 压缩功能的。我们可以在 server.xml 配置文件中的 Connector 节点中配置如下参数,来实现对指定资源类型进行压缩。
compression="on"
# 打开压缩功能
compressionMinSize="50"
# 启用压缩的输出内容大小,默认为2KB
noCompressionUserAgents="gozilla, traviata"
# 对于以下的浏览器,不启用压缩
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
# 哪些资源类型需要压缩
提示:
Tomcat 的压缩是在客户端请求服务器对应资源后,从服务器端将资源文件压缩,再输出到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程 HTML、CSS、Javascript和Text,它可以节省40% 左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP、JSP、ASP、Servlet,SHTML等输出的网页也能进行压缩,压缩效率也很高。但是,压缩会增加 Tomcat 的负担,因此最好采用Nginx + Tomcat 或者 Apache + Tomcat 方式,将压缩的任务交由 Nginx/Apache 去做。
7、多虚拟主机
强烈建议不要使用 Tomcat 的虚拟主机,推荐每个站点使用一个实例。即,可以启动多个 Tomcat,而不是启动一个 Tomcat 里面包含多个虚拟主机。因为 Tomcat是多线程,共享内存,任何一个虚拟主机中的应用崩溃,都会影响到所有应用程序。虽然采用多实例的方式会产生过多的开销,但至少保障了应用程序的隔离和安全。
8、关闭war自动部署
默认 Tomcat 是开启了对war包的热部署的。为了防止被植入木马等恶意程序,因此我们要关闭自动部署。
修改实例:
<Host name=
"localhost"
appBase=
""
unpackWARs=
"false"
autoDeploy=
"false"
>
9、禁用 Tomcat 管理页面
我们线上是不使用 Tomcat 默认提供的管理页面的,因此都会在初始化的时候就把这些页面删掉。这些页面是存放在 Tomcat 安装目录下的webapps目录下的。
我们只需要删除该目录下的所有文件即可。
当然,还有涉及管理页面的2个配置文件 host-manager.xml 和 manager.xml 也需要一并删掉。这两个文件存放在 Tomcat 安装目录下的conf/Catalina/localhost目录下。