Tomcat性能调优

1、集成apache

      虽然Tomcat也可以作web服务器,但是处理静态html的速度比不上apache,且其作为web服务器的功能远不如Apache,因此把apache和tomcat集成起来,讲html和jsp功能部分进行明确的分工,让tomcat只处理jsp部分,其他的由apache、IIS等web服务器去处理,因此大大提供tomcat的运行效率。

部署方式:

  • 安装apache服务器
  • 部署tomcat
  • 将mod_jk.so拷贝到modules目录下面
  • 修改httpd.conf和mod_jk.conf

使用场景:大量使用静态页面的应用系统

2、apache+tomcat集群

     对于并发要求很高的系统,需要采取负载均衡的方式来分担tomcat服务器的压力。

负载均衡实现的四种方式:

1)通过DNS,但只能简单的实现轮流分配,不能处理故障。

2)基于MS IIS、Windows 2003 Server本身自带的负载均衡服务。

3)硬件方式,通过交换机功能或专门的负载均衡设备来实现。

4)通过一台负载均衡服务器实现,上面安装软件。

    使用apache http server做负载均衡器、集群节点使用tomcat来实现上述的第4种方式,即:apache+tomcat集群来实现负载均衡。该方式可以最大程度的发挥服务器的性能,可以在配置较高的服务器上部署多个tomcat,也可以在多台服务器上分别部署tomcat,apache和tomcat整合的方式使用JK的方式。经验证,系统对大用户量使用的响应方面,apache+3tomcat集群>apache+2tomcat集群>apache集成tomcat>单个tomcat,并且采用多个tomcat时,如果一个tomcat宕机,系统可以继续使用,所以硬件系统性能足够优越的情况下,需要尽量发挥软件的性能,可以采用增加tomcat集群的方式。

apache+tomcat集群使用的配置文件:

  • httpd.conf
  • mod_jk.conf(对jk信息的配置,包括jk的路径等)
  • workers.properties(对tomcat服务器的连接定义文件)

apache需要调整的运行参数:

1)设置mpm参数

  • ThreadPerChild---用于设置每个进程的线程数(在windows环境下默认是64,最大值是1920,建议值100~500)
  • MaxRequestPerChild---每个子进程能够处理的最大请求数(很大程度上取决于服务器的内存,建议值3000)

2)关闭DNS和名字解析

  • HostnameLookup  off

3)打开UseCanonicalName模块

  • UseCanonicalName on

4)关闭多余模块,一般来说,不需要加载的模块有mod_include.so、mod_autoindex.so、mod_access.so、mod_auth.so

5)打开KeepAlive支持

  •      KeepAlive on
  •      KeepAliveTimeout 15
  •      MaxKeepAliveRequests 1000

部署方式:

  • 安装apache服务器
  • 部署tomcat集群
  • 将mod_jk.so拷贝到modules目录下面
  • 修改相关配置文件

使用场景:并发用户数高的系统

3、JVM调优

1)JDK版本选择

     在满足项目需要的前提下,尽量选用版本较高的JVM,一般来说高版本产品在速度和效率上比低版本会有改进。 JDK1.4比JDK1.3性能提高了近10%-20%,JDK1.5比JDK1.4性能提高25%-75%。

2)JVM版本选择 

     SUN的JVM动态库有client和server两个版本,分别针对桌面应用和服务器应用做了相应的优化,client版本加载速度较快,server版本加载速度较慢但运行起来较快。在命令行输入 java -version 可以看到jvm目前配置的是哪个版本。如果要修改jvm的版本,可更改默认java.exe调用的jvm.dll,这个由jvm.cfg决定。编辑%JAVA_HOME%/jre/lib/i386/jvm.cfg文件,里面第一行写的是-client(默认就是client版本),把第二行的-server KNOWN 放到第一行, 如下所示:

-server KNOWN 
-client KNOWN 
-hotspot ALIASED_TO -client 
-classic WARN 
-native ERROR 
-green ERROR

然后重启tomcat,在命令行下输入java -version ,就可以看到类似如下的信息:

java version "1.6.0_13" 
Java(TM) SE Runtime Environment (build 1.6.0_13-b03 ) 
Java HotSpot(TM) Server VM (build 11.3-b02 , mixed mode)

     表明Tomcat已经修改为使用Server版本的JVM,可进行对比测试,对比一下Client版本的JVM和Server版本的性能差异,从而决定采用哪个版本的JVM。另外,也可以考虑更换其它厂商的JVM,例如Oracle的JRockit等。


3)JVM参数调优

JVM启动参数配置例子:
export JAVA_OPTS="-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true “

4、tomcat容器本身调优

1)禁用DNS查询

    消除因DNS查询所消耗的时间,可以在tomcat种关闭DNS查询:

  •     enableLookups="false"   ---server.xml文件中

2)调整线程数

      Tomcat使用线程池加速响应速度来处理请求。在Java中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同的地址空间。多线程帮助程序员写出CPU最大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。 

     Tomcat4中可以通过修改minProcessors和maxProcessors的值来控制线程数

       这些值在安装后就已经设定为默认值并且是足够使用的,但是随着站点的扩容而改大这些值。minProcessors服务器启动时创建的处理请求的线程数应该足够处理一个小量的负载。也就是说,如果一天内每秒仅发生5次单击事件,并且个每请求任务处理需要1秒钟,那么预先设置线程数为5就足够了。但在你的站点访问量较大时就需要设置更大的线程数,指定为参数maxProcessors的值。maxProcessors的值也是有上限的,应防止流量不可控制(或者恶意的服务攻击),从而导致超出了虚拟机使用内存的大小。如果要加大并发连接数,应同时加大这两个参数(但别忘了:web server允许的最大连接数还受制于操作系统的内核参数设置)。

  Tomcat5对这些参数(server.xml中)进行了调整:

  • maxThreads:Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数
  • acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。
  • connnectionTimeout网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。
  • minSpareThreads:Tomcat初始化时创建的线程数
  • maxSpareThreads:一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。

    最好的方式是多设置几次并且进行测试,观察响应时间和内存使用情况。在不同的机器、操作系统或虚拟机组合的情况下可能会不同,而且并不是所有人的web站点的流量都是一样的,因此没有一刀切的方案来确定线程数的值。

5、ARP库

     所谓的Apache Tomcat Native library其实叫APR,全称为:Apache Portable Runtime and Tomcat。Apache Tomcat Native library是Apache为了提升Tomcat的性能开发的一套本地化Socket、Thread、IO组件,也就是说它有高级IO功能, 操作系统级别的功能调用, 以及本地进程处理等等, 这些都能使Tomcat更像一个Web Server(像Apache那样), 而不是只能用来解释JSP, 也就是说提升单独的Tomcat作为服务器的吞吐性能。

      Tomcat中使用APR库,其实就是在Tomcat中使用JNI(Java Native Interface的缩写,中文为JAVA本地调用)的方式来读取文件以及进行网络传输。可以大大提升Tomcat对静态文件的处理性能,同时如果你使用了HTTPS方式传输的话,也可以提升SSL的处理性能。一般在Windows下,可以直接下载编译好的二进制版本的dll库文件来使Tomcat启用APR,一般建议拷贝库文件tcnative-1.dll到Tomcat的bin目录下。而在Linux下,可以直接解压和安装bin目录下的tomcat_native.tar.gz文件。

怎么才能判断Tomcat是否已经启用了APR库呢?方法是通过看Tomcat的启动日志catalina.out:

如果没有启用APR,则启动日志一般有这么一条: org.apache.coyote.http11.Http11Protocol start 

如果启用了APR,则这条日志就会变成: org.apache.coyote.http11.Http11AprProtocol start

     APR资料参考:http://tomcat.apache.org/tomcat-5.5-doc/apr.html

安装部署APR:

1. Windows下安装APR
    用于Windows的APR是一个名称为:tcnative-1.dll的文件。可到下面网址下载匹配版本的tcnative-1.dll,把下载的tcnative-1.dll文件放到<$JAVA_HOME>/bin目录下,启动Tomcat就可以看到Tomcat已经加载部署了APR:Loaded APR based Apache Tomcat Native library 1.1.20

2. Linux下安装APR
1)安装APR
到http://apr.apache.org下载apr-1.2.12.tar.gz,然后用以下命令安装:
tar -xvf apr-1.2.12.tar.gz
cd apr-1.2.12
./configure --prefix=/tomcat/apr
make
make install

2)安装APR-UTIL
到http://apr.apache.org下载apr-util-1.2.12.tar.gz,然后用以下命令安装:
tar -xvf apr-util-1.2.12.tar.gz
cd apr-util-1.2.12
./configure --prefix=/tomcat/apr --with-apr=/tomcat/apr
make
make install

3)安装tomcat native library
cd /usr/local/tomcat/bin
tar zxvf tomcat-native.tar.gz
cd tomcat-native-1.1.10-src/jni/native
./configure --prefix=/tomcat/apr -- with-apr=/tomcat/apr –with-java-home=/usr/jdk
make
make install

4)编辑tomcat/bin/catalina.sh
将JAVA_OPTS="$CATALINA_OPTS -Djava.library.path= tomcat/apr/lib"
加在# ----- Execute The Requested Command -----------------------------------------前面

5)添加环境变量
# vi /etc/profile
添加:
export LD_LIBRARY_PATH=/usr/local/apr/lib

6)重启Tomcat后,查看Tomcat输出日志,可见APR成功加载了
# vim /usr/local/tomcat/logs/catalina.out

信息: Loaded Apache Tomcat Native library 1.1.10.
2008-7-8 10:20:27 org.apache.catalina.core.AprLifecycleListener init
信息: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
2008-7-8 10:20:27 org.apache.coyote.http11.Http11AprProtocol init

6、Compression压缩

     HTTP压缩可以大大提高浏览网站的速度,它的原理是在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML,CSS,JS, Text,可以节省40%左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP, JSP, ASP, Servlet, SHTML等输出的网页也能进行压缩,压缩效率惊人。

  • compression="on" 打开压缩功能
  • compressionMinSize="2048" 启用压缩的输出内容大小,这里面默认为2KB
  • noCompressionUserAgents="gozilla, traviata" 对于以下的浏览器,不启用压缩
  • compressableMimeType="text/html,text/xml" 压缩类型

(server.xml中)配置以后是这样的:

复制代码
<Connector port="8088" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443"
               compression="on" 
               compressionMinSize1="2048" 
               noCompressionUserAgents="gozilla, traviata" 
               compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"/>
复制代码

Tomcat调优综述:

     根据以上分析,如果想要Tomcat达到最优的效果,首先要争取使得操作系统以及网络资源达到最优,并且最好使用高版本的JDK。对于有大量静态页面的系统,采用Apache集成Tomcat的方式,把静态页面交由Apache处理,动态部分交由Tomcat处理,能极大解放Tomcat的处理能力。使用ARP库也能极大的提高Tomcat对静态文件的处理能力。对于并发要求较高的系统,采用Apache加Tomcat集群的方式,将负载分别分担到多个Tomcat上,能很大的提高系统的性能,充分利用硬件资源。同时需要对Tomcat自身进行优化,包括增大内存、调节并发线程数等。

重要参数说明:

1)maxThreads - 连接线程数监控与调整

     maxThreads是最大并发线程数,如果同时的并发请求量超过这个值,Tomcat也不会再增加线程,这时并发请求将进入队列。增加maxThreads的值可以加大Tomcat的并发处理能力,但是设置过高的maxThreads值也会对性能带来影响,占有过多的系统资源,甚至造成Tomcat崩溃。线程数可在Tomcat的Manager状态页面进行监控。

针对Tomcat7进行试验,以说明maxThreads对于Tomcat服务器性能的影响:

Tomcat堆内存设置为256M,用LoadRunner启动50个虚拟用户测试JpetStore主页面(http://192.168.1.101:8080/jpetstore/shop/index.shtml),可得到以下测试结果:
(1)、默认配置maxThreads=200,平均事务响应时间:0.390
(2)、maxThreads=5,平均事务响应时间:0.355
(3)、maxThreads=50,平均事务响应时间:0.369
(4)、maxThreads=3,平均事务响应时间:0.559
可以看到,当maxThreads设置比较小时,Tomcat处理请求的速度有所下降。如果我们在测试脚本中设置严格的并发(插入集合点lr_Rendezvous函数),可得到以下结果:
(1)、maxThreads=3,平均事务响应时间:2.609
(2)、maxThreads=50,平均事务响应时间:0.597
可以看到,在高强度的并发情况下,如果Tomcat的maxThreads值设置比较小,会严重影响性能,一般需要设置大于最大同时并发请求数。
注意:一般Web服务器允许的最大连接数还受限制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右。在CentOS 中可以用以下命令查看Socket最大连接数:ulimit -a
其中的open files是允许打开的最大文件数,CentOS默认是1024。这个数值可通过修改vi /etc/security/limits.conf文件来设置,例如修改为32768,可在文件后添加:
* soft nofile 32768
* hard nofile 32768
保存,重启系统后就生效了。

为了证明这个Linux系统参数对Socket连接的影响,我们可以进行对比试验,修改/etc/security/limits.conf:
* soft nofile 200
* hard nofile 200
在LoadRunner中启动200个VU并发(设置集合点),在Controller的Connection和Connection per Second图中看到连接数偏少(相比起默认设置的1024):

(1)、参数设置为200
平均事务响应时间:19.664
Connections:177.376
Connections per Second-New Connection:28.082
Connections per Second-Connection Shutdown:28.082

(2)、参数设置为1024(默认设置)
平均事务响应时间:2.712
Connections:315.136
Connections per Second-New Connection:114.000
Connections per Second-Connection Shutdown:114.000

在Socket连接建立受到限制的情况下,Tomcat的并发处理能力也受到明显的影响,平均事务响应时间急剧上升。

2)connectionTimeout – 连接超时的设置

     connectionTimeout是Connector从接受连接到提交URI的等待的时间(单位是毫秒),默认设置为60000(即60秒)。connectionTimeout如果设置得比较小的话,可能造成大量用户访问网站时出现“502”异常。

telnet试验:直接用telnet连上tomcat,如果不保持持续地输入,则连接很快会断开(如果connectionTimeout时间设置得比较小的话);如果一直不停输入,连接会被继续保持。

关于该项的详细解释和配置可参考tomcat帮助文档:http://tomcat.apache.org/tomcat-5.5-doc/config/http.html

3)acceptCount - 最大排队数的设置

     acceptCount是指当所有线程都已经被用于处理请求时,允许多少新的连接请求进入排队队列等候处理,当队列满的时候,任何新的请求都将被拒绝。默认设置值为100。
配置例子如下:

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="800" acceptCount="1000"/>


其中:maxThreads是Tomcat启动的最大线程数,默认值为200;acceptCount是当Tomcat起动的线程数达到最大时,接受排队的请求个数,默认值为100,这两个值一起工作,可能出现下面三种情况:

  • 情况1:接受一个请求,此时Tomcat启动的线程数还没有到达maxThreads设置的个数,Tomcat会启动一个线程来处理此请求。
  • 情况2:接受一个请求,此时Tomcat启动的线程数已经到达maxThreads设置的个数,Tomcat会把此请求放入等待队列,等待空闲线程可用。
  • 情况3:接受一个请求,此时Tomcat启动的线程数已经到达maxThreads设置的个数,而且等待队列中的请求个数也达到了acceptCount设置的个数,此时Tomcat会直接拒绝此次请求,返回connection refused的错误。

关于Sun’s HotSpot JVM的其它与性能相关的调整参数参考:

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#PerformanceTuning

原文地址:https://www.cnblogs.com/hllnj2008/p/3993592.html