Tomcat(JVM)性能调优

Tomcat架构图

Tomcat与JVM版本优化
Tomcat的运行是基于Java的虚拟机。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等。

Tomcat与内存泄漏
Tomcat 默认可以使用的内存为128MB(不同的版本有所区别),在较大型的应用项目中,这点内存是不够的,需要调大,否则很容易出现“Out of Memery”的问题。 
在Windows 下,修改配置文件 {tomcat_home}/bin/catalina.bat,在Linux/Unix 下,修改配置文件 {tomcat_home}/bin/catalina.sh,增加如下设置:
JAVA_OPTS=‘-Xms 【初始化内存大小】 -Xmx 【可以使用的最大内存】‘
需要根据服务器可用内存把这个两个参数值调大。
另外,对于SUN的JVM,MaxPermSize参数的调整也比较重要。PermSize的大小决定了保持对象(类、方法)的大小。如果碰到“OutOfMemoryError: PermGen”的错误提示,应该考虑调整这个参数的大小。SUN JVM默认保留64MB作为PermSize大小。
关于Sun’s HotSpot JVM的其它与性能相关的调整参数,请读者参考:
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#PerformanceTuning

maxThreads - 连接线程数监控与调整
可通过修改Tomcat安装目录的Conf文件夹中的配置文件server.xml文件来调整Tomcat最大连接线程数。maxThreads是最大并发线程数,如果同时的并发请求量超过这个值,Tomcat也不会再增加线程,这时并发请求将进入队列。增加maxThreads的值可以加大Tomcat的并发处理能力,但是设置过高的maxThreads值也会对性能带来影响,占有过多的系统资源,甚至造成Tomcat崩溃。
线程数可在Tomcat的Manager状态页面进行监控,如图7.8所示:

图7.8 监控Tomcat线程数
下面针对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的并发处理能力也受到明显的影响,平均事务响应时间急剧上升。

connectionTimeout – 连接超时的设置
connectionTimeout是Connector从接受连接到提交URI的等待的时间(单位是毫秒),默认设置为60000(即60秒)。
这个设置在$tomcat/conf/server.xml中:
<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="2000" disableUploadTimeout="true" />
关于该项的详细解释和配置,读者可参考tomcat帮助文档:
http://tomcat.apache.org/tomcat-5.5-doc/config/http.html
connectionTimeout如果设置得比较小的话,可能造成大量用户访问网站时出现“502”异常。
connectionTimeout并不是指整个连接处理的时间,而是指从开始接受连接到开始处理请求的URI这段等待时间,读者可以用telnet做个试验来验证:
直接用telnet连上tomcat,如果什么都不输入,socket很快会断开,输入完整的GET请求包,能够获得输出(服务器响应包)。如果不保持持续地输入,则连接很快会断开(如果connectionTimeout时间设置得比较小的话);如果一直不停输入,连接会被继续保持。
$ telnet localhost 8080

GET /index.jsp HTTP/1.1
Accept-Language: zh-cn
Connection: Keep-Alive
Host: 192.168.0.11
Content-Length: 36

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的错误。

Tomcat Native library(APR)的配置
所谓的Apache Tomcat Native library其实叫APR,全称为:Apache Portable Runtime and Tomcat。可以通过下面地址访问:
http://tomcat.apache.org/tomcat-5.5-doc/apr.html
Apache Tomcat Native library是Apache 为了提升 Tomcat 的性能开发的一套本地化 Socket、Thread、IO组件,也就是说它有高级 IO 功能, 操作系统级别的功能调用, 以及本地进程处理等等, 这些都能使Tomcat更像一个Web Server(像Apache那样), 而不是只能用来解释JSP, 也就是说提升单独的Tomcat作为服务器的吞吐性能。
如果不配置Tomcat Native library,则启动Tomcat时会提示:
2011-7-3 23:59:16 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performanc
e in production environments was not found on the java.library.path: E:\Program
Files\Java\jdk1.6.0_13\bin;.;E:\WINDOWS\Sun\Java\bin;E:\WINDOWS\system32;...
Linux下可用如下命令在Tomcat的日志输出文件中查看到上述提示:
head logs/catalina.out
下面介绍如何安装和部署APR:
1、Windows下安装APR
用于Windows的APR是一个名称为:tcnative-1.dll 的文件。可到下面网址下载匹配版本的tcnative-1.dll:
http://www.apache.org/dist/tomcat/tomcat-connectors/native/1.1.20/binaries/win32/
把下载的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

Connector - 连接器的配置
Tomcat从5.5版本开始,支持以下四种Connector的配置分别为:
(1)、NIO
NIO利用了APR提供的本地IO,能提升Tomcat的并发处理能力,配置例子如下所示:
<Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443"/>
(2)、HTTP
HTTP是Tomcat默认配置的连接器,性能比较稳定,但是效率不是很高,配置的例子如下所示:
<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443"/> 
(3)、tomcatThreadPool
tomcatThreadPool使用了线程池的技术,客户端请求可重用线程池中的线程来处理,节省了重新分配线程的开销,配置的例子如下所示:
<Connector executor="tomcatThreadPool"
port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
(4)、tomcatThreadPool + NIO
tomcatThreadPool可以组合NIO来提供服务,即在NIO的基础上加入线程池,配置的例子如下所示:
<Connector executor="tomcatThreadPool"
port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
读者可讲Tomcat的连接器分别按这四种方式配置,然后做一下对比测试,查看一下性能的差异。
一般来说,第二种配置方式(HTTP)的性能会比较稳定,但是也是最差的,而这种方式是Tomcat的默认配置;第一种配置方式(NIO)的会有性能波动,但整体效率是比较高的;第三种配置方式(tomcatThreadPool)性能波动比较大;第四种配置方式(tomcatThreadPool + NIO)是在NIO的基础上加入线程池,可能是程序处理更复杂了,因此性能不见得比NIO强。

资料:

JVM参数对J2EE性能优化的影响:http://sinckyzhang.blog.sohu.com/149067215.html

Tomcat(JVM)性能调优,布布扣,bubuko.com

时间: 2024-08-05 19:35:33

Tomcat(JVM)性能调优的相关文章

Tomcat 和 JVM 性能调优总结

Tomcat性能调优: 找到Tomcat根目录下的conf目录,修改server.xml文件的内容.对于这部分的调优,我所了解到的就是无非设置一下Tomcat服务器的最大并发数和Tomcat初始化时创建的线程数的设置,当然还有其他一些性能调优的设置,下图是我根据我机子的性能设置的一些参数值,给各位详细解释一下吧: 1.URIEncoding=”UTF-8″ :设置Tomcat的字符集.这种配置我们一般是不会设置的,因为关于乱码的转换我们会在具体项目中具体处理,直接修改Tomcat的字符集未免过于

(转)JVM性能调优之生成堆的dump文件

转自:http://blog.csdn.net/lifuxiangcaohui/article/details/37992725 最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一记录. 一.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为: New(年轻代) Tenured(年老代) 永久代(Perm) 其中New和Tenured属于堆内存,堆内存会从JVM启动参数(-Xmx:3G)指定的内存中分配,Perm不属于堆内存,有虚拟机直接分配,但可以

JVM性能调优(转)

本文转自:http://www.cnblogs.com/chen77716/archive/2010/06/26/2130807.html 最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一记录. 一.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为: New(年轻代) Tenured(年老代) 永久代(Perm) 其中New和Tenured属于堆内存,堆内存会从JVM启动参数(-Xmx:3G)指定的内存中分配,Perm不属于堆内存,有虚拟机直接分

JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解

现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 ...... 这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求.本文将对一些常用的JVM性能调优监控工具进行介绍,希望能起抛砖引玉之用.本文参考了网上很多资料,难以一一列举,在此对这些资料的

[转]JVM性能调优监控工具

http://my.oschina.net/feichexia/blog/196575?p=1#comments JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat.hprof等小巧的工具,本博客希望能起抛砖引玉之用,让大家能开始对JVM性能调优的常用工具有所了解. 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争

JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解

JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat等小巧的工具,本博客希望能起抛砖引玉之用,让大家能开始对JVM性能调优的常用工具有所了解. 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 ...... 这些问题在日常开发中可能被很多人忽视(比如有的

JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解(转VIII)

JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat等小巧的工具,本博客希望能起抛砖引玉之用,让大家能开始对JVM性能调优的常用工具有所了解. 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 ...... 这些问题在日常开发中可能被很多人忽视(比如有的

JVM 性能调优实战之:一次系统性能瓶颈的寻找过程

玩过性能优化的朋友都清楚,性能优化的关键并不在于怎么进行优化,而在于怎么找到当前系统的性能瓶颈.性能优化分为好几个层次,比如系统层次.算法层次.代码层次...JVM 的性能优化被认为是底层优化,门槛较高,精通这种技能的人比较少.笔者呆过几家技术力量不算弱的公司,每个公司内部真正能够进行 JVM 性能调优的人寥寥无几.甚至没有.如是乎,能够有效通过 JVM 调优提升系统性能的人往往被人们冠以"大牛"."大师"之类的称呼.其实 JVM 本身给我们提供了很多强大而有效的监

JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码

本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 提升到 20 (提升了 7 倍),并准确定位系统瓶颈:我们应用里静态对象不是太多.有大量的业务线程在频繁创建一些生命周期很长的临时对象,代码里有问题.那么问题来了,如何在海量业务代码里边准确定位这些性能代码?本文将介绍如何使用阿里开源工具 TProfiler 来定位这些性能代码,成功解决掉了 GC 过于频繁的性能瓶颈,并最终在上次优化的基础

JVM性能调优1:JVM性能调优理论及实践(收集整理)

本系列包括: JVM性能调优1:JVM性能调优理论及实践(收集整理) JVM性能调优2:JVM性能调优参数整理 JVM性能调优3:JVM_堆溢出分析过程和命令 JVm性能调优4:GC日志分析 JVM性能调优5:Heap堆分析方法 注:本文部分内容收集整理了网上的资料. 1.      内存结构 1.1.     分代结构图 注意: 在JVM中,非堆内存,根据模式不同分为不同的几个部分. -Server下:非堆包括:持久代和代码缓存(Code cache) -client下:非堆包括:持久代.代码