以下为转发来,具体地址为 http://blog.csdn.net/chen3888015/article/details/7432488
环境centos5.7 tomcat6
http://apr.apache.org/download.cgi
1、修改tomcat让其支持NIO
编辑Tomcat目录下面的conf子目录下面的server.xml文件
vi /opt/tomcat6/conf/server.xml
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
修改成支持NIO的类型,配置如下 :
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol " connectionTimeout="20000" redirectPort="8443" />
Tomcat的四种基于HTTP协议的Connector性能比较
Tomcat从5.5版本开始,支持以下四种Connector的配置分别为:
<Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443"/>
<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443"/>
<Connector executor="tomcatThreadPool"
port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector executor="tomcatThreadPool"
port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
我们姑且把上面四种Connector按照顺序命名为 NIO, HTTP, POOL, NIOP
为了不让其他因素影响测试结果,我们只对一个很简单的jsp页面进行测试,这个页面仅仅是输出一个Hello World。假设地址是 http://tomcat1/test.jsp
我们依次对四种Connector进行测试,测试的客户端在另外一台机器上用ab命令来完成,测试命令为: ab -c 900 -n 2000 http://tomcat1/test.jsp ,最终的测试结果如下表所示(单位:平均每秒处理的请求数):
NIO HTTP POOL NIOP281 | 65 | 208 | 365 |
666 | 66 | 110 | 398 |
692 | 65 | 66 | 263 |
256 | 63 | 94 | 459 |
440 | 67 | 145 | 363 |
由这五组数据不难看出,HTTP的性能是很稳定,但是也是最差的,而这种方式就是Tomcat的默认配置。NIO方式波动很大,但没有低于280 的,NIOP是在NIO的基础上加入线程池,可能是程序处理更复杂了,因此性能不见得比NIO强;而POOL方式则波动很大,测试期间和HTTP方式一样,不时有停滞。
由于linux的内核默认限制了最大打开文件数目是1024,因此此次并发数控制在900。
尽管这一个结果在实际的网站中因为各方面因素导致,可能差别没这么大,例如受限于数据库的性能等等的问题。但对我们在部署网站应用时还是具有参考价值的。
来自:http://www.javayou.com/diary/143691518
2、增加tomcat的处理线程数
编辑Tomcat目录下面的conf子目录下面的server.xml文件
maxThreads :Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数。
acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。
connectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。
minSpareThreads:Tomcat初始化时创建的线程数。
maxSpareThreads:一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。
<Connector port="19101" maxHttpHeaderSize="8192" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" maxThreads="150" acceptCount="100" enableLookups="false" disableUploadTimeout="true" />
当tomcat线程数增大,但没有超过最大线程数时,平均响应时间会增大,但这不意味着tomcat在线程增多时响应速度变慢.在测试中发现,由于线程数增多,在请求时需要排队,导致一部分请求会一直排队,随着线程数的增多,排队等待的最大时间也会越来越大,而这些大数据才是导致平均响应时间变大的罪魁祸首.响应时间大于3s的请求占总请求的比例一直维持在3%-5%.
http://blog.csdn.net/spider_zhcl/article/details/6167095
3、tomcat内存空间的设置
编辑Tomcat目录下面的bin子目录下面的catalina.sh文件
常见tomcat内存错误1:java.lang.OutOfMemoryError: Java heap space
使用Java程序从数据库中查询大量的数据时出现异常
在JVM中如果98%的时间是用于GC(Garbage Collection)且可用的Heap size 不足2%的时候将抛出此异常信息。
整体意思是超出内存堆空间的错误
OutOfMemeoryError:超出内存的错误
要加“m”说明是MB,否则就是KB了,在启动tomcat时会 报内存不足。
-server表示以server模式运行,运行效率比默认的client高很多
-Xms:初始值
-Xmx:最大值
-Xmn:最小值
一般的JAVA程序在运行都可以通过中-Xms -Xmx来调整应用程序的初始内存和最大内存:
如:java -Xms64m -Xmx128m a.jar.
tomcat的启动程序是包装过的,不能直接使用java -Xms64m -Xmx128m tomcat.*来改变内存的设置,而是只要去改变catalina.sh文件的值就行。
常见tomcat内存错误2:java.lang.OutOfMemoryError: PermGen space
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
问题的关键是SUN 的JVM把内存分了不同的区,其中一个就是permenter区用来存放用得非常多的类和类描述。本来SUN设计的时候认为这个区域在JVM启动的时候就固定了,但他没有想到现在动态映射会用得这么广泛。而且这个区域有特殊的垃圾收回机制,现在的问题是动态加载类到这个区域后,gc根本没办法回收!,现在只能通过加大内存来解决。
因为对于操作系统,请求内存的系统调用会占用大量的cpu时间,所以频繁的请求、释放内存将会导致性能的严重下降。所以对于jvm,最好的方式就是尽量多占用内存作为heap,少释放甚至不释放空闲的heap给操作系统以减少消耗在内存请求、释放操作上的cpu时间。
设置NewSize、MaxNewSize相等,"new"的大小最好不要大于"old" 的一半,原因是old区如果不够大会频繁的触发主GC,大大降低了性能
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64,由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4
常见tomcat内存错误3:OutOfMemoryError: unable to create new native thread.
无法创建新的线程。
每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的 400兆内存里创建这个物理线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。
这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。
给出一个有关能够创建线程的最大个数的估算公式:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads
对于jdk1.5而言,假设操作系统保留120M内存:
1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads
1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads
因此:我们需要结合不同情况对tomcat内存分配进行不同的诊断才能从根本上解决问题。
常见tomcat内存错误3:java "Too small initial heap" 错误
Error occurred during initialization of VM
Too small initial heap for new size specified
Error occurred during initialization of VM
Too small initial heap for new size specified
在网上google了下,说是Xmx设置小了。
将catalina.sh文件中的:
export JAVA_OPTS=-Xms128m -Xmx1024m
改为:
set VM_ARGS=-Xms256m -Xmx1024m
程序运行正常。
原因分析:
启动应用时,通过使用-X选项来分配JVM的存储。
具体解决方案
centos 环境下面的操作
vi /opt/tomcat6/bin/catalina.sh
在文件头部的注释下面,加入下面的内容
#tomcat堆内存设置,假设内存空间为4G
export JAVA_OPTS='-server -Xms1024m -Xmx1024m -Xmn256m -XX:PermSize=128m -XX:MaxNewSize=512m -XX:MaxPermSize=512m '
#让tomcat自己管理内存
export JAVA_OPTS=$JAVA_OPTS -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="$CATALINA_HOMEconflogging.properties"
windows下面的tomcat
#tomcat堆内存设置,假设内存空间为4G
set JAVA_OPTS='-server -Xms1024m -Xmx1024m -Xmn256m -XX:PermSize=128m -XX:MaxNewSize=512m -XX:MaxPermSize=512m '
#让tomcat自己管理内存
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="%CATALINA_HOME%conflogging.properties"
访问网页的时候后台经常错误,今天在http://7sunet.iteye.com/blog/291247这个文章中有具体分析了一下原因
org.apache.tomcat.util.http.Parameters processParameters
造成以上问题的有这么几种原因:
2、访问/test.jsp?p1=1&p2=&p3=3...
3、访问/test.jsp?p1=1&&p2=2...
4、访问/test.jsp?action=save&....
5、表单提交时,存在<input name="" value="***" />这样的域
总之,代码编写的不规范容易带来这样的问题。
另外warn类型的日志,可以在服务器日志中找,Tomcat6好像在logs/catalina.log中