Tomcat优化

Posted 礁之

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat优化相关的知识,希望对你有一定的参考价值。


Tomcat优化从两部分出发,一个是JVM,一个是Tomcat本身

一、Tomcat双实例(部署两台Tomcat)

  1. 在主配置文件中,直接把所有的Service区域复制一下,修改两个连接器的端口号不冲突即可,域名也不能相同
+[root@rzy ~]# vim /usr/local/tomcat/conf/server.xml  #删除注释
。。。。。。
 17   <Service name="Catalina">
 18     <Connector port="8080" protocol="HTTP/1.1"  #端口号不能相同,域名和网页存放路径也不能相同
 19                connectionTimeout="20000"
 20                redirectPort="8443" />
 21     <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> #8080和8009的端口
 22     <Engine name="Catalina" defaultHost="localhost">
 23       <Realm className="org.apache.catalina.realm.LockOutRealm">
 24         <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
 25                resourceName="UserDatabase"/>
 26       </Realm>
 27       <Host name="www.aaa.com"  appBase="webapps"
 28             unpackWARs="true" autoDeploy="true">
 29         <Context docBase="/web/webapp" path="" reloadable="false"></Context>
 30       </Host>
 31     </Engine>
 32   </Service>
 33   <Service name="Catalina">
 34     <Connector port="8081" protocol="HTTP/1.1"   #改成8081和8010
 35                connectionTimeout="20000"
 36                redirectPort="8443" />
 37     <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
 38     <Engine name="Catalina" defaultHost="localhost">
 39       <Realm className="org.apache.catalina.realm.LockOutRealm">
 40         <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
 41                resourceName="UserDatabase"/>
 42       </Realm>
 43       <Host name="www.bbb.com"  appBase="webapps"
 44             unpackWARs="true" autoDeploy="true">
 45         <Context docBase="/web2/webapp" path="" reloadable="false"></Context>
 46       </Host>
 47     </Engine>
 48   </Service>
 49 </Server>
#保存退出
[root@rzy ~]# /usr/local/tomcat/bin/shutdown.sh  #重新启动
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@rzy ~]# /usr/local/tomcat/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@rzy ~]# netstat -anpt | grep java  #查看端口,发现有五个端口,一个8005是关闭tomcat的端口,另外四个就是两个实例的连接器的端口
tcp6       0      0 :::8080                 :::*                    LISTEN      17004/java          
tcp6       0      0 :::8081                 :::*                    LISTEN      17004/java          
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      17004/java          
tcp6       0      0 :::8009                 :::*                    LISTEN      17004/java          
tcp6       0      0 :::8010                 :::*                    LISTEN      17004/java    

测试 (端口要注意修改)创建实例成功
在这里插入图片描述

  1. 第二种方法简单粗暴,直接装两台tomcat,路径不一样即可(略)

二、Tomcat定义默认页面、页面超时和静止列出目录

[root@rzy ~]# vim /usr/local/tomcat/conf/web.xml  #进入网页配置文件
。。。。。。
 110         <init-param>
 111             <param-name>listings</param-name>    
 112             <param-value>false</param-value>  #禁止列出列表
 113         </init-param>
 114         <load-on-startup>1</load-on-startup>
 115     </servlet>
。。。。。。
 581     <session-config>
 582         <session-timeout>30</session-timeout>  #页面超时时间,默认30秒
 583     </session-config>
。。。。。。
 4679     <welcome-file-list>
 4680         <welcome-file>index.html</welcome-file> #默认可以解析的页面,默认有三个
 4681         <welcome-file>index.htm</welcome-file>
 4682         <welcome-file>index.jsp</welcome-file>
 4683     </welcome-file-list>
 4684 
。。。。。。

三、禁用AJP协议连接器

(1)HTTP和AJP

  • Tomcat中,默认安装完之后,会有三个监听端口,也就是三个连接器,分别是连接HTTP的TCP的8080端口、连接其他Web服务的TCP的8009端口和用来关闭Tomcat的8005端口。8009是在Tomcat和其他HTTP服务器建立连接时使用的
  • Tomcat最主要的功能是提供Servlet/JSP容器,虽然也可以作为Java Web服务器,但是在处理静态资源(静态页面)的速度,以及提供的Web服务器管理功能方面都是不如其他专业的HTTP服务器,比如apache和nginx还有windows的IIS。
  • 在使用Tomcat时,通常都会配合其他Web服务器一起使用,Tomcat只处理动态页面(jsp页面)
  • 可以使用AJP的常用Web服务器只有Apache一个,但是现在最常用的都是使用Nginx+Tomcat来使用,AJP是用不上的,所以可以关闭AJP减少系统资源损耗

(2)Web客户端请求Tomcat服务器上JSP资源的两种方式

在这里插入图片描述

(3)禁用步骤

[root@rzy ~]# vim /usr/local/tomcat/conf/server.xml  #注释掉8009AJP连接器
。。。。。。
116     <!--<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />--> #增加注释
117 
。。。。。。
#保存退出
[root@rzy ~]# /usr/local/tomcat/bin/shutdown.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@rzy ~]# /usr/local/tomcat/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@rzy ~]# netstat -anpt | grep java  #查看端口发现只剩下一个8080和8005的端口了
tcp6       0      0 :::8080                 :::*                    LISTEN      1523/java           
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      1523/java   

四、Tomcat配置网页压缩传输

[root@rzy ~]# vim /usr/local/tomcat/conf/server.xml  #修改主配置文件
。。。。。。
 69     <Connector port="8080" protocol="HTTP/1.1"
 70                connectionTimeout="20000"
 71                redirectPort="8443" 
 72                compression="on"  #开启网页传输压缩
 73                compressionMinSize="50"  #设置大小最小的压碎文件,单位是字节,即只要大于指定字节就进行压缩
 74                noCompressionUserAgents="gozilla,traviata"  #指定某种浏览器不进行压缩
 75                compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"/> #压缩文件的格式
。。。。。。
#保存退出
[root@rzy ~]# /usr/local/tomcat/bin/shutdown.sh  #重启Tomcat
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@rzy ~]# /usr/local/tomcat/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.

五、Tomcat的三种模式

(1)同步异步、阻塞和非阻塞


  • 同步: 调用者向被调用者发送任务请求,被调用者在完成任务请求的时间内,调用者会一直等待被调用者完成任务请求,在被调用者完成任务请求后,调用者才会执行下一个请求并且继续向被调用者发送任务请求。

例如: 老板给员工小王布置一个任务,老板在小王完成这个任务之前,会一直等待小王,在这个过程中老板不会去做其他事情


  • 异步: 调用者向被调用者发送任务请求,被调用者完成任务请求后会通过状态、通知或者回调机制主动通知调用者,这个期间调用者可以继续执行下一个请求

例如: 老板分配给员工小王一个任务,小王在做完这个任务后会向老板汇报,这个过程中老板不会进行等待,而是去做其他事情


  • 同步和异步的区别:

同步:被调用者不会主动向调用者返回任务的状态,在返回状态之前,调用者需要一直等待被调用者完成任务

异步:被调用者会主动向调用者返回任务的状态,在返回状态之前,调用者可以执行下一个请求


  • 阻塞: 指I/O操作需要彻底完成之后才会返回到用户空间,在调用结果返回之前,调用者被挂起,不能执行下一个操作

例如: 手洗衣服,没洗完之前手是干不了其他事情的


  • 非阻塞: 指I/O操作被调用之后会立刻返回一个用户状态,无需等待I/O操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起

例如: 使用全自动洗衣机,不需要占用使用者的时间,洗完之后去拿就行,在这个期间使用者可以去干其他的事情


(2)Tomcat的三种模式

Tomcat有三种模式,分别是BIO、NIO、AIO

  • java BIO: 同步并阻塞,服务器实验模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程去处理,但是如果连接后线程并没有做任何事情的话,就会造成系统资源的损耗,可以通过线程池机制去改善**(基本上实际应用中已经淘汰)**

  • java NIO: 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器采用轮询方式检查连接是否有I/O请求,当连接有I/O请求时,才启动一个线程进行处理

  • java AIO(NIO2.0): 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,当I/O请求没有完成时,服务器是不会创建线程去处理的

Tomcat三种模式的使用场景

  • BIO: BIO方式适用于连接数目比较小并且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用种,是JDK1.4以前的唯一选择,但是程序直观理解简单
  • NIO: NIO方式适用于连接数目多并且连接比较短(轻操作)的架构,例如聊天服务器,并发局限于应用种,变成比较复杂,JDK1.4版本后开始支持

访问http://192.168.100.202:8080/manager/status,即点击Status进行状态页面,移到最下面查看连接器的模式都端口
在这里插入图片描述

(3)修改模式

因为Bio模式基本已经不用了,所以不进行修改BIO模式,而且在Tomcat的7版本以上默认就是NIO模式,所以只进行修改AIO模式

[root@rzy ~]# rpm -e apr --nodeps #检查是否安装apr
[root@rzy ~]# yum -y install apr apr-devel #使用yum安装apr
。。。。。。
完毕!
[root@rzy ~]# cp /usr/local/tomcat/bin/tomcat-native.tar.gz /root/ #复制tomcat-native.tar.gz源码包到root下
[root@rzy ~]# tar xf tomcat-native.tar.gz   #解压
[root@rzy ~]# cd tomcat-native-1.2.12-src/native/  #进入解压目录
[root@rzy native]# ./configure --with-apr=/usr/bin/apr-1-config && make && make install  #配置编译安装
。。。。。。
Libraries have been installed in:  #提示这个表示安装成功
   /usr/local/apr/lib
。。。。。。
[root@rzy native]# cd
[root@rzy ~]# vim /usr/local/tomcat/bin/catalina.sh 
。。。。。。
616 CATALINA_OPTS="-Djava.library.path=/usr/local/apr/lib"  #末尾添加
#保存退出
[root@rzy ~]# vim /usr/local/tomcat/conf/server.xml 
。。。。。。
 69     <Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" #修改protocol
 70                connectionTimeout="20000"
 71                compression="on"          #删除8443端口,防止端口冲突
 72                compressionMinSize="50"
 73                noCompressionUserAgents="gozilla,traviata"
 74                compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"/>
。。。。。。
#保存退出
[root@rzy ~]# vim /etc/profile  #修改系统配置文件,添加全局变量
。。。。。。
 77 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/java/bin:/usr/local/java
 78 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib  #添加
#保存退出
[root@rzy ~]# source /etc/profile  #执行系统配置文件,使配置生效
[root@rzy ~]# /usr/local/tomcat/bin/shutdown.sh   #重启服务
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@rzy ~]# /usr/local/tomcat/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@rzy ~]# netstat -anpt | grep java 
tcp6       0      0 :::8080                 :::*                    LISTEN      2614/java           
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      2614/java   

查看Tomcat的状态

在这里插入图片描述

六、生产环境Tomcat配置

******即实际工作中,Tomcat的常用配置
[root@rzy ~]# vim /usr/local/tomcat/conf/server.xml #修改配置文件
。。。。。。
 69     <Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
 70         URIEncoding="UTF-8"  
 71         minSpareThreads="25"
 72         maxSpareThreads="75"
 73         enableLookups="false"        
 74         disableUploadTimeout="true" 
 75         connectionTimeout="20000"
 76         acceptCount="300"
 77         maxThreads="300"
 78         maxProcessors="1000"
 79         minProcessors="5"
 80         compression="on"
 81         compressionMinSize="2048"
 82         compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
 83         redirectPort="8443"/>
。。。。。。
#保存退出
******注释
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" #8080连接器区域,这里配置的是apr模式
URIEncoding="UTF-8"    #配置字符编码类型
minSpareThreads="25"   #Tomcat连接器初始话时创建的线程数
maxSpareThreads="75"   #Tomcat连接器的最大空闲线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的线程,默认50
enableLookups="false"          #屏蔽DNS查询,开启这个会影响Tomcat的访问速度,DNS查询即用户使用DNS去解析服务器的域名或ip 
disableUploadTimeout="true"    #表示当执行servlet时,是否允许Servlet容器使用一个不同的、更长的超时连接,ture允许
connectionTimeout="20000"    #网络超时时间
acceptCount="300"      #允许的最大连接数,一般设置为maxProcessors的1.5倍即可,满了之后用户请求会被拒绝
maxThreads="300"       #用户请求最大线程数,默认值为200
maxProcessors="1000"   #最大连接线程数,即并发处理的最大请求数,默认值为75,一旦创建的线程超过这个值,TOmcat就会关闭不再需要的线程
minProcessors="5"      #最小空闲连接线程数,用来提高系统处理性能,默认值为10
compression="on"       #开启网页传输压缩
compressionMinSize="2048"  #指定压缩的输出内容大小,单位时字节,这里默认是2kb
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"/> #网页压缩的类型
redirectPort="8443"   #开启安全通道ssl

#注意!!!!!!:
当前端是由nginx作为反向代理时,不需要启动Tomcat的网页传输压缩功能,即80到82行不需要配置



maxKeepAliveRequests=“1”:nginx动态的转给tomcat,nginx是不能keepalive的,而tomcat端默认开启了keepalive,会等待keepalive的timeout,默认不设置就是使用connectionTimeout。所以必须设置tomcat的超时时间,并关闭tomcat的keepalive。否则会产生大量tomcat的socket timewait。maxKeepAliveRequests=”1”就可以避免tomcat产生大量的TIME_WAIT连接,从而从一定程度上避免tomcat假死。

七、JVM性能调优

Tomcat本身还是运行在JVM上的,通过对JVM参数的调整我们可以使Tomcat拥有更好的性能。

目前针对JVM的调优主要有两个方面:内存调优和垃圾回收策略调优

  • jvm内存管理机制:

什么是堆(Heap)和非堆(Non-heap)内存?

按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。
堆内存就是运行java程序的内存,非堆内存就是JVM本身的内存,本身内存代表方法区、JVM内部处理或优化所需的内存(如IT编译后的代码缓存)、每个类结构(如运行时常数池、资源和方法数据)以及方法和构造的代码都在非堆内存中0


  • 堆内存分配

JVM初始分配的堆内存是由-Xms指定的,默认大小是物理内存的1/64,JVM最大分配的堆内存由-Xmx指定,默认大小是物理内存的1/4。

默认空余内存小于40%时,JVM就会增大堆内存知道-Xmx的最大限制,当空余内存大于70%时,JVM会减少堆内存到-Xms的最小限制,因此服务器一般设置-Xms和-Xmx相同,避免在每次GC后调整堆内存的大小,减少耗费的资源

说明:如果-Xmx 不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM,不是Throwable的,无法用try...catch捕捉。

  • 非堆内存分配

JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

-server选项下默认MaxPermSize为64m,-client选项下默认MaxPermSize为32m。

还有一说:MaxPermSize缺省值和-server -client选项相关


**XX:MaxPermSize设置过小会导致java.lang.OutOfMemoryError: PermGen space 也就是内存益出。 **

为什么会内存益出:
(1)这一部分内存用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同
(2)GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS 的话,就很可能出现PermGen space错误。
这种错误常见在web服务器对JSP进行pre compile的时候。


  • 修改内存等 JVM相关配置
[root@rzy ~]# vim /usr/local/tomcat/bin/catalina.sh 
。。。。。。
 139 CLASSPATH=          #放在CLASSPATH=下面
 140 JAVA_OPTS="-Xms2048M -Xmx2048M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M"  #添加
。。。。。。
#保存退出
[root@rzy ~]# /usr/local/tomcat/bin/shutdown.sh  #重启服务
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@rzy ~]# /usr/local/tomcat/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/java
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.

******注释:
-server:启用 JDK的 server 版本;
-Xms:虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能;
-Xmx:Java虚拟机可使用堆的最大内存;建议均设为物理内存的一半。不可超过物理内存。 
-XX:PermSize:设定内存的永久保存区初始大小;
-XX:MaxPermSize:设定内存的永久保存区初始大小最大值;

以上是关于Tomcat优化的主要内容,如果未能解决你的问题,请参考以下文章

使用 C++ 反转句子中的每个单词需要对我的代码片段进行代码优化

如何优化C ++代码的以下片段 - 卷中的零交叉

从JVM的角度看JAVA代码--代码优化

Tomcat8优化--代码优化

Tomcat部署及优化

Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段