转载 http://blog.csdn.net/chen3888015/article/details/7432488
最近在做压力测试,用户数不到60,就没有办法响应,用了下面的优化流程并发性能提高了很多
环境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 NIOP
281 | 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_HOME\conf\logging.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%\conf\logging.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中
tomcat6升级的新特性
tomcat6如何配置maxSpareThreads,minSpareThreads参数
Tomcat6 maxSpareThreads参数不再被支持,minSpareThreads需要在 Executor 中配置
Standard 的配置和 NIO 的配置都可使用: acceptCount
使用 Executor 可能会有一点性能损失,但是高负载的环境下,会通过一个 FIFO 的队列公平得处理请求
升级到 tomcat6.0.18 ,修改 conf/ server.xml 调整为:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="200" minSpareThreads="50"/>
采用 NIO 的配置:
<Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" enableLookups="false"
maxThreads="200" acceptCount="500" acceptorThreadCount="1" connectionTimeout="5000"
redirectPort="8443" />
http://apr.apache.org/download.cgi
APR 1.4.6 is the best available version |
|
APR-util 1.4.1 is the best available version |
|
APR iconv 1.2.1 is the best available version |
|
Tomcat Native Connector |
|
http://tomcat.heanet.ie/native/1.1.14/source/
wget http://apache.etoak.com//apr/apr-1.4.6.tar.gz
wget http://mirror.bjtu.edu.cn/apache//apr/apr-iconv-1.2.1.tar.gz
wget http://mirror.bit.edu.cn/apache//apr/apr-util-1.4.1.tar.gz
wget http://labs.mop.com/apache-mirror//tomcat/tomcat-connectors/native/1.1.23/source/tomcat-native-1.1.23-src.tar.gz
Apache Tomcat Native library 是干什么的呢? 一般情况下,APR开发包很轻易理解为仅仅是一个开发包,不过事实上并不是。目前,完整的APR实际上包含了三个开发包:apr、apr-util以及apr-iconv,每一个开发包分别独立开发,并拥有自己的版本。
Apache Tomcat Native library 是干什么的呢?
这是 Apache 为了提升 Tomcat 的性能搞的一套本地化 Socket, Thread, IO 组件也就是说它有高级 IO 功能, 操作系统级别的功能调用, 以及本地进程处理等等, 这些都能使 Tomcat 更像一个 Web Server(像Apache那样), 而不是只能用来解释JSP, 也就是说提升单独的 Tomcat 作为服务器的吞吐性能. 一般情况下,APR开发包很轻易理解为仅仅是一个开发包,不过事实上并不是。目前,完整的APR实际上包含了三个开发包:apr、apr-util以及 apr-iconv,每一个开发包分别独立开发,并拥有自己的版本。 apr包含了一些通用的开发组件,包括mmap,文件等等,前面已经描述过。 apr-util也是包含了一些常用的开发组件。这些组件与apr目录下的相比,它与apache的关系更加密切一些。比如存储段和存储段组,加密等等。 apr-iconv包中的文件主要用于实现iconv编码。目前的大部分编码转换过程都是与本地编码相关的。在进行转换之前必须能够正确地设置本地编码。因此假如两个非本地编码A和B需要转换,则转换过程大致为A->Local以及Local->B或者B->Local以及 Local->A。 XPG2 标准中另外定义了一组全新的函式接口ICONV,该接口是一种更广义的字集转换系统。也是一个与本地编码无关的字集转换系统。APR中也支持这种字集转换系统,为此它提供了完整的实现。Apr-iconv正是为此目的而产生。 1、安装apr
# tar zxvf apr-1.3.8.tar.gz 2、安装apr-iconv # tar -zxvf apr-iconv-1.2.1.tar.gz 3、安装apr-util # tar zxvf apr-util-1.3.9.tar.gz 4、安装tomcat-native(tomcat在/usr/local/tomcat) http://labs.mop.com/apache-mirror//tomcat/tomcat-connectors/native/1.1.23/source/tomcat-native-1.1.23-src.tar.gz # cp tomcat-native-1.1.18-src.tar.gz /usr/local/tomcat/bin/ 5、设置 apr 的环境变量: # vi /etc/profile 启动 tomcat 后, 看日志: Dec 5, 2009 3:25:39 PM org.apache.catalina.core.AprLifecycleListener init
转载请保留出处!http://hi.baidu.com/linjingmin/blog/item/bd00c8fcd98a7488b901a0ab.html |
解决:The Apache Tomcat Native library which allows optimal performance in production environments was not found
5.5开始就支持apr了,启动的时候会有一句话,显示没找到tomcat native,这就是指apache apr,能增强IO的能力。
在tomcat发行版里有一个tomcat-native.tar.gz文件,可以解开来编译,如果嫌麻烦就去下载已编译好的版本:
http://tomcat.heanet.ie/native/
下载tcnative-1.dll,如果需要SSL,就再下载openssl.exe文件以获得SSL支持。
把dll放到tomcat下bin目录,再重新启动就行了,启动速度没变化,但是访问速度有提高,特别是并发的时候,建议使用。
---
The Apache Tomcat Native library which allows optimal performance in production environments was not found ……
解决方法:
相关文档:http://tomcat.apache.org/tomcat-6.0-doc/apr.html
去这里http://tomcat.heanet.ie/native/下载最新版本的tcnative-1.dll放到Tomcat的安装目录\Bin下
之后重启Tomcat就OK了。
比如现在我已下载了V1.1.14的tcnative-1.dll,启动时信息变成:
首先在你的TOMCAT的目录下Tomcat 5.5\conf找到server.xml文件
配置如下信息:
- <Service name="Catalina">
- <!--The connectors can use a shared executor, you can define one or more named thread pools-->
- <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
- maxThreads="1000" minSpareThreads="50" maxIdleTime="600000"/>
name
The name used to reference this pool in other places in server.xml. The name is required and must be unique.
这个是线程池的名字,必须唯一,我们在后面的配置里要用到这个东西
namePrefix
(String) The name prefix for each thread created by the executor. The thread name for an individual thread will be namePrefix+threadNumber
线程的名字前缀,用来标记线程名字的,这样每个线程就用这个前缀加上线程编号了,比如
catalina-exec-1
catalina-exec-2
maxThreads
(int) The max number of active threads in this pool, default is 200
允许的最大线程池里的线程数量,默认是200,大的并发应该设置的高一些,反正只是限制而已,不占用资源
minSpareThreads
(int) The minimum number of threads always kept alive, default is 25
最小的保持活跃的线程数量,默认是25.这个要根据负载情况自行调整了。太小了就影响反应速度,太大了白白占用资源。
maxIdleTime
(int) The number of milliseconds before an idle thread shutsdown, unless the number of active threads are less or equal to minSpareThreads. Default value is 60000(1 minute)
超过最小活跃线程数量的线程,如果空闲时间超过这个设置后,会被关别。默认是1分钟。
threadPriority
(int) The thread priority for threads in the executor, the default is Thread.NORM_PRIORITY
线程的等级。默认是Thread.NORM_PRIORITY
第二步
在 Connector里指定使用共享线程池
http://vod.sjtu.edu.cn/help/Article_Print.asp?ArticleID=1387
转至http://blog.csdn.net/hulefei29/archive/2009/01/21/3849150.aspx
(一)
目前市场上常用的开源Java Web容器有Tomcat、Resin和Jetty。其中Resin从V3.0后需要购买才能用于商业目的,而其他两种则是纯开源的。可以分别从他们的网站上下载最新的二进制包和源代码。
作为Web容器,需要承受较高的访问量,能够同时响应不同用户的请求,能够在恶劣环境下保持较高的稳定性和健壮性。在HTTP服务器领域,Apache HTTPD的效率是最高的,也是最为稳定的,但它只能处理静态页面的请求,如果需要支持动态页面请求,则必须安装相应的插件,比如mod_perl可以处理Perl脚本,mod_python可以处理Python脚本。
上面介绍的三中Web容器,都是使用Java编写的HTTP服务器,当然他们都可以嵌到Apache中使用,也可以独立使用。分析它们处理客户请求的方法有助于了解Java多线程和线程池的实现方法,为设计强大的多线程服务器打好基础。
Tomcat是使用最广的Java Web容器,功能强大,可扩展性强。最新版本的Tomcat(5.5.17)为了提高响应速度和效率,使用了Apache Portable Runtime(APR)作为最底层,使用了APR中包含Socket、缓冲池等多种技术,性能也提高了。APR也是Apache HTTPD的最底层。可想而知,同属于ASF(Apache Software Foundation)中的成员,互补互用的情况还是很多的,虽然使用了不同的开发语言。
Tomcat 的线程池位于tomcat-util.jar文件中,包含了两种线程池方案。方案一:使用APR的Pool技术,使用了JNI;方案二:使用Java实现的ThreadPool。这里介绍的是第二种。如果想了解APR的Pool技术,可以查看APR的源代码。
ThreadPool默认创建了5个线程,保存在一个200维的线程数组中,创建时就启动了这些线程,当然在没有请求时,它们都处理“等待”状态(其实就是一个while循环,不停的等待notify)。如果有请求时,空闲线程会被唤醒执行用户的请求。
具体的请求过程是: 服务启动时,创建一个一维线程数组(maxThread=200个),并创建空闲线程(minSpareThreads=5个)随时等待用户请求。 当有用户请求时,调用 threadpool.runIt(ThreadPoolRunnable)方法,将一个需要执行的实例传给ThreadPool中。其中用户需要执行的实例必须实现ThreadPoolRunnable接口。 ThreadPool 首先查找空闲的线程,如果有则用它运行要执行ThreadPoolRunnable;如果没有空闲线程并且没有超过maxThreads,就一次性创建 minSpareThreads个空闲线程;如果已经超过了maxThreads了,就等待空闲线程了。总之,要找到空闲的线程,以便用它执行实例。找到后,将该线程从线程数组中移走。 接着唤醒已经找到的空闲线程,用它运行执行实例(ThreadPoolRunnable)。 运行完ThreadPoolRunnable后,就将该线程重新放到线程数组中,作为空闲线程供后续使用。
由此可以看出,Tomcat的线程池实现是比较简单的,ThreadPool.java也只有840行代码。用一个一维数组保存空闲的线程,每次以一个较小步伐(5个)创建空闲线程并放到线程池中。使用时从数组中移走空闲的线程,用完后,再“归还”给线程池。
(二)
ThreadPool提供的仅仅是线程池的实现,而如何使用线程池也是有很大学问的。让我们看看Tomcat是如何使用ThreadPool的吧。
Tomcat有两种EndPoint,分别是AprEndpoint和PoolTcpEndpoint。前者自己实现了一套线程池(其实这和Tomcat 老版本的方案是相同的,至今Tomcat中还保留着老版本的线程池,PoolTcpEndpoint也有类似的代码,通过“策略”可以选择不同的线程池方案)。我们只关注PoolTcpEndpoint如何使用ThreadPool的。
首先,PoolTcpEndpoint创建了一个ThreadPoolRunnable实例——LeaderFollowerWorkerThread,实际上该实例就是接收(Accept)并处理(Process)用户socket请求。接着将该实例放进ThreadPool中并运行,此时就可以接收用户的请求了。
当有Socket请求时,LeaderFollowerWorkerThread首先获得了Socket实例,注意此时LeaderFollowerWorkerThread并没有急着处理该Socket,而是在响应Socket消息前,再次将LeaderFollowerWorkerThread放进ThreadPool中,从而它(当然是另外一个线程了)可以继续处理其他用户的Socket请求;接着,拥有Socket的LeaderFollowerWorkerThread再来处理该用户的Socket请求。
整个过程与传统的处理用户Socket请求是不同的,也和Tomcat老版本不同。传统的处理方法是:有一个后台运行的监听线程负责统一处理接收(注意只是“接收”)Socket请求,当有新的Socket请求时,将它赋值给一个Worker线程(通常是唤醒该线程),并有后者处理Socket请求,监听线程继续等待其他Socket请求。所以整个过程中有一个从Listener到Worker切换的过程。
而新版本Tomcat很有创造性的使用了另外一种方法,正如前文所描述的,接收和处理某个用户Socket请求的始终是由一个线程全程负责,没有切换到其他线程处理,少了这种线程间的切换是否更有效率呢?我还不能确认。不过这种使用方式确实有别于传统模式,有种耳目一新的感觉。
(三)
除了Tomcat外,Jetty是另外一个重要的Java Web容器,号称“最小的”Web容器,从Jetty的源代码规模可以看出它确实比较小。而且它的ThreadPool的实现也非常简单,整个代码ThreadPool代码只有450行左右,可见小巧之极。
ThreadPool代码位于com.mortbty.thread包中,其中最重要的方法是dispatch()和内部类PoolThread。顾名思义,dispatch方法主要是将Runnable实例派给线程池中的空闲PoolThread,由后者运行Runnable。
还是看看整个过程吧。首先,ThreadPool创建_minThreads个空闲PoolThread,并把它们添加到空闲线程队列中。当需要运行 Runnable时,首先查找是否有空闲的PoolThread,如果有空闲的,这由它处理;如果没有并且PoolThread并没有超过 _maxThreads个时,则创建一个新的PoolThread,并由这个新创建的PoolThread运行Runnable;如果 PoolThread超过了_maxThreads,则一直等待有空闲的PoolThread出现。在PoolThread运行之前,必须把该 PoolThread从空闲线程队列中移走。
再来看看PoolThread的实现吧。和所有的Worker线程一样,用一个while(flag){wait();}循环等待Runnable的到来,当有Runnable被ThreadPool.dispatch()时,该PoolThread就运行Runnable;当运行完成后,再“归还”给空闲线程队列。
Jetty如何使用ThreadPool?整个Jetty只使用了一个ThreadPool实例,具体入口在 org.mortbay.jetty.Server中被实例化的,Connector中也使用Server的ThreadPool处理用户的Socket 请求。Connector是处理用户Socket请求的入口,一个Connector创建_acceptors个Acceptor,由Acceptor处理用户Socket请求时,当有Socket请求时,就创建一个Connection放到线程池中处理,而Acceptor继续处理其他的Socket请求。这是个传统的Listener和Worker处理方式。
(四)
在这些Java Web容器中,Resin算得上很特别的,小巧稳定,而且效率很高。在这些Java Web容器中,算它的效率最高了。很多大型的网站中都能找到它的身影。Resin从3.0版本后开始走“特色”的开源路,与MySql很相似——如果用于商业目的,则需要买它的License。但对于个人研究而言,这已经不错了,在网站上可以下载除了涉及License的源代码外其他所有代码。
说Resin特别,还主要是由于它的性能出众,即使在很多企业级应用中也能派上用场。Resin的数据库连接池做的很不错,效率非常高。不过这里我们讨论它的线程池,看看有何特别之处。
Resin的ThreadPool位于com.caucho.util.ThreadPool中,不过这个类的命名有点蹊跷,更恰当的命名是 ThreadPoolItem,因为它确实只是一个普通的Thread。那线程调度何管理在哪里呢?也在这个类中,不过都是以静态函数方式提供的,所以这个类起到了两重作用:线程池调度和Worker线程。也由于这种原因,Resin实例中只有一个线程池,不像Tomcat和Jetty可以同时运行多个线程池,不过对于一个系统而言,一个线程池足够了。
和其他线程池实现方式不同的是,Resin采用链表保存线程。如果有请求时,就将Head移走并唤醒该线程;待运行完成后,该线程就变成空闲状态并且被添加到链表的Head部分。另外,每一个线程运行时都要判断当前空闲线程数是否超过_minSpareThreads,如果超过了,该线程就会退出(状态变成Dead),也从链表中删除。
Resin如何使用该ThreadPool?所有需要用线程池的地方,只需调用ThreadPool. Schedule(Runnable)即可。该方法就是一个静态函数,顾名思义,就是将Runnable加到ThreadPool中待运行。
Resin使用的还是传统方法:监听线程(com.caucho.server.port.Port),系统中可以有多个Port实例,前提端口号不同,比如有80和8080端口;另外就是Worker线程,其实就是ThreadPool中的空闲线程。Port本身是一个Thread,在启动时,会在 ThreadPool中运行5个线程——TcpConnection同时等待用户请求,当有用户请求时,其中的一个会处理。其他继续等待。当处理用户请求完成后,还可以重用这些TcpConnection,这与Jetty的有所不同,Jetty是当有用户请求时,才创建连接,处理完成后也不会重用这些连接,效率会稍差一些。
另外Resin有两个后台运行线程:ThreadLauncher和ScheduleThread,前者负责当空闲线程小于最小空闲线程时创建新的线程;而后者则负责运行实际的Runnable。我觉得有的负责,没有必要用一个线程来创建新线程,多此一举。不过ScheduleThread是必须的,因为它就是Worker线程。
(五)
介绍了tomcat、jetty和resin三种Java Web容器的线程池后,按照惯例应该比较它们的优缺点。不过先总结线程池的特点。
线程池作为提高程序处理数据能力的一种方案,应用非常广泛。大量的服务器都或多或少的使用到了线程池技术,不管是用Java还是C++实现,线程池都有如下的特点:
线程池一般有三个重要参数:
1. 最大线程数。在程序运行的任何时候,线程数总数都不会超过这个数。如果请求数量超过最大数时,则会等待其他线程结束后再处理。
2. 最大共享线程数,即最大空闲线程数。如果当前的空闲线程数超过该值,则多余的线程会被杀掉。
3. 最小共享线程数,即最小空闲线程数。如果当前的空闲数小于该值,则一次性创建这个数量的空闲线程,所以它本身也是一个创建线程的步长。
线程池有两个概念:
1. Worker线程。工作线程主要是运行执行代码,有两种状态:空闲状态和运行状态。在空闲状态时,类似“休眠”,等待任务;处理运行状态时,表示正在运行任务(Runnable)。
2. 辅助线程。主要负责监控线程池的状态:空闲线程是否超过最大空闲线程数或者小于最小空闲线程数等。如果不满足要求,就调整之。
如果按照上述标准去考察这三个容器就会发现:Tomcat实现的线程池是最完备的,Resin次之,而Jetty最为简单。Jetty没有控制空闲线程的数量,可能最后空闲线程数会达到最大线程数,影像性能,毕竟即使是休眠线程也会耗费CPU时钟的。
谈谈Resin的线程池。Resin的实现比Tomcat复杂些。也有上述三个参数,也有两个概念,这与Tomcat相当。但考虑到如何使用ThreadPool时,Resin也要复杂些。
或许由于Resin的ThreadPool是单间模式的,所有使用ThreadPool的线程都是相同设置,比如相同的最大线程数,最大空闲线程数等,在使用它时会多些考虑。比如在控制最大Socket连接数时,com.caucho.server.port.Port还要有自己的一套控制“数量”的机制,而无法使用ThreadPool所特有的控制机制。所以使用起来比Tomcat复杂。
Tomcat使用ThreadPool却很简单。由于Tomcat的ThreadPool可以有不同的实例存在,很方便的定制属于自己的“数量”控制,直接用ThreadPool控制Socket连接数量。所以代码也比较清爽。
如果要使用线程池,那就用Tomcat的ThreadPool吧。
Tomcat6开始使用APR,提高其Http Connector这个module的性能,主要作用是使用Tomcat直接作为前台服务器,而不是作为后台服务器,如果是使用Apache+Tomcat的形式,Apache作为前端服务器,Tomcat只是作为后台服务器的话,且AJP要使用Nio的方式,就不能使用APR的功能,也就是说使用了Nio就无法使用APR,所以在部署高性能应用场景下,你要作如下决策:
使用tomcat但不使用APR,那么你必须使用apache,来弥补http链接的性能瓶颈。
否则同时使用APR和NIO启动的时候会有警告:
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.port' to '8009' did not find a
matching property.
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.redirectPort' to '8443' did no
t find a matching property.
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.maxThreads' to '256' did not f
ind a matching property.
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.maxSpareThreads' to '97' did n
ot find a matching property.
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.minSpareThreads' to '50' did n
ot find a matching property.
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.URIEncoding' to 'UTF-8' did no
t find a matching property.
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.connectionTimeout' to '20000'
did not find a matching property.
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.keepAliveTimeout' to '1000' di
d not find a matching property.
2010-2-26 15:28:08 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'channelNioSocket.bufferSize' to '16384' did not
find a matching property.
2010-2-26 15:28:08 org.apache.catalina.core.AprLifecycleListener init
信息: Loaded APR based Apache Tomcat Native library 1.1.14.
2010-2-26 15:28:08 org.apache.catalina.core.AprLifecycleListener init
信息: APR capabilities: IPv6 [false], sendfile [true], accept filters [false], random [true].
2010-2-26 15:28:09 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
信息: Using a shared selector for servlet write/read
2010-2-26 15:28:09 org.apache.coyote.http11.Http11NioProtocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
2010-2-26 15:28:09 org.apache.coyote.ajp.AjpAprProtocol init
信息: Initializing Coyote AJP/1.3 on ajp-0
2010-2-26 15:28:09 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 1042 ms
2010-2-26 15:28:09 org.apache.catalina.core.StandardService start
信息: Starting service Catalina
2010-2-26 15:28:09 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/6.0.18
2010-2-26 15:28:10 org.apache.coyote.http11.Http11NioProtocol start
信息: Starting Coyote HTTP/1.1 on http-8080
2010-2-26 15:28:10 org.apache.coyote.ajp.AjpAprProtocol start
信息: Starting Coyote AJP/1.3 on ajp-0
2010-2-26 15:28:10 org.apache.catalina.startup.Catalina start
信息: Server startup in 869 ms
这个时候,tomcat启动时因为在tomcat6.0.18\bin下有找到tcnative-1.dll文件,所以protocol使用的是org.apache.coyote.ajp.AjpAprProtocol.class
如果删除tcnative-1.dll后,再启动Tomcat,一切正常,没能警告
2010-2-26 15:31:47 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not fou
nd on the java.library.path: C:\jdk1.6\bin;.;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\jdk1.6\bin;C:\jdk
1.6\jre\bin;C:\Program Files\Borland\Delphi7\Bin;C:\Program Files\Borland\Delphi7\Projects\Bpl\;C:\Perl\site\bin;C:\Perl
\bin;D:\oracle\product\10.2.0\client_1\bin;D:\oracle\product\10.2.0\db_1\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\S
ystem32\Wbem;C:\Program Files\Common Files\Thunder Network\KanKan\Codecs;C:\Program Files\Microsoft SQL Server\80\Tools\
BINN;C:\PROGRA~1\Tcl\bin;C:\SFU_INSTALL\common\;D:\apache-ant-1.7.0\bin;C:\Program Files\SSH Communications Security\SSH
Secure Shell
2010-2-26 15:31:47 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
信息: Using a shared selector for servlet write/read
2010-2-26 15:31:47 org.apache.coyote.http11.Http11NioProtocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
2010-2-26 15:31:47 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 761 ms
2010-2-26 15:31:47 org.apache.catalina.core.StandardService start
信息: Starting service Catalina
2010-2-26 15:31:47 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/6.0.18
2010-2-26 15:31:48 org.apache.coyote.http11.Http11NioProtocol start
信息: Starting Coyote HTTP/1.1 on http-8080
2010-2-26 15:31:48 org.apache.jk.common.ChannelSocket init
信息: JK: ajp13 disabling channelSocket
2010-2-26 15:31:48 org.apache.jk.common.ChannelNioSocket init
信息: JK: ajp13 listening on /0.0.0.0:8009
2010-2-26 15:31:48 org.apache.jk.server.JkMain start
信息: Jk running ID=0 time=0/32 config=null
2010-2-26 15:31:48 org.apache.catalina.startup.Catalina start
信息: Server startup in 930 ms
但是这时候protocal使用的是org.apache.jk.server.JkCoyoteHandler.class
<Connector protocol="AJP/1.3" port="0"
channelNioSocket.port="8009"
channelNioSocket.redirectPort="8443"
channelNioSocket.maxThreads="256"
channelNioSocket.maxSpareThreads="97"
channelNioSocket.minSpareThreads="50"
channelNioSocket.URIEncoding="UTF-8"
URIEncoding="UTF-8"
channelNioSocket.connectionTimeout="20000"
channelNioSocket.keepAliveTimeout="1000"
channelNioSocket.bufferSize="16384"/>
http://windows9834.blog.163.com/blog/static/27345004201012633648519/
http://vod.sjtu.edu.cn/help/Article_Print.asp?ArticleID=1387
http://grantbb.iteye.com/category/35866
]http://lianj-lee.iteye.com/blog/547485
http://brofe.iteye.com/blog/233399
Tomcat可以使用APR来提供超强的可伸缩性和性能,更好地集成本地服务器技术。APR(Apache Portable Runtime)是一个高可移植库,它是Apache HTTP Server 2.x的核心。APR有很多用途,包括访问高级IO功能(例如sendfile,epoll和OpenSSL),OS级别功能(随机数生成,系统状态等等),本地进程管理(共享内存,NT管道和UNIX sockets)。这些功能可以使Tomcat作为一个通常的前台WEB服务器,能更好地和其它本地web技术集成,总体上让Java更有效率作为一个高性能web服务器平台而不是简单作为后台容器。
按照官方说明需要:
- APR library
- OpenSSL libraries
openssl 可以用 yum install openssl-devel,apr还是下载*.gz来安装。
apr-1.3.2.tar.gz
apr-util-1.3.2.tar.gz
两个可以在 http://apache.mirror.phpchina.com/apr/ 找到。
tomcat-native.tar.gz 可以在tomcat/bin目录下找到。
安装 apr
- # wget http://apache.mirror.phpchina.com/apr/apr-1.3.2.tar.gz
- # tar zxvf apr-1.3.2.tar.gz
- # cd apr-1.3.2
- # ./configure
- # make
- # make install
- # wget http://apache.mirror.phpchina.com/apr/apr-1.3.2.tar.gz
- # tar zxvf apr-1.3.2.tar.gz
- # cd apr-1.3.2
- # ./configure
- # make
- # make install
apr 默认安装在 /usr/local/apr
安装 apr-util
- # wget http://apache.mirror.phpchina.com/apr/apr-util-1.3.2.tar.gz
- # tar zxvf apr-util-1.3.2.tar.gz
- # cd apr-util-1.3.2
- # ./configure --with-apr=/usr/local/apr
- # make
- # make install
- # wget http://apache.mirror.phpchina.com/apr/apr-util-1.3.2.tar.gz
- # tar zxvf apr-util-1.3.2.tar.gz
- # cd apr-util-1.3.2
- # ./configure --with-apr=/usr/local/apr
- # make
- # make install
安装 tomcat-native
- # cd /usr/local/tomcat-6.0.18/bin
- # tar zxvf tomcat-native.tar.gz
- # cd tomcat-native-1.1.14-src/jni/native
- # ./configure --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.6.0_11
- # make
- # make install
- # cd /usr/local/tomcat-6.0.18/bin
- # tar zxvf tomcat-native.tar.gz
- # cd tomcat-native-1.1.14-src/jni/native
- # ./configure --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.6.0_11
- # make
- # make install
设置 apr 的环境变量:
- # vi /etc/profile
- // 后面添加以下内容
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
- //使profile生效,
- # source /etc/profile
- # vi /etc/profile
- // 后面添加以下内容
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
- //使profile生效,
- # source /etc/profile
启动 tomcat 后, 看日志:
- # bin/startup.sh
- # head logs/catalina.out
- // 可以看到以下结果:
- 信息: Loaded APR based Apache Tomcat Native library 1.1.14.
- 2009-1-13 11:12:51 org.apache.catalina.core.AprLifecycleListener init
- 信息: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
- # bin/startup.sh
- # head logs/catalina.out
- // 可以看到以下结果:
- 信息: Loaded APR based Apache Tomcat Native library 1.1.14.
- 2009-1-13 11:12:51 org.apache.catalina.core.AprLifecycleListener init
- 信息: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
好了, 可以运行了,但没有测试其性能提升多少。
參考自:http://www.chinajvm.com/main/helpcontent.jsp?id=5320b71a1eb098e2011ee230a2311367
http://blog.chenlb.com/2009/01/install-apache-portable-runtime-or-tomcat-native-on-tomcat.html
一般在Windows下,可以直接下载编译好的二进制版本的dll库文件来使Tomcat启用APR,下载地址是:http://tomcat.heanet.ie/native/
今天要说的是在linux下面怎么使用它,
- 环境
- CentOs 5
- 所需软件
- Tomcat 5.5.27
- apr-1.3.3.tar.gz
- apr-util-1.3.4.tar.gz
- tomcat-native-1.1.16-src.tar.gz
- 环境
- CentOs 5
- 所需软件
- Tomcat 5.5.27
- apr-1.3.3.tar.gz
- apr-util-1.3.4.tar.gz
- tomcat-native-1.1.16-src.tar.gz
安装过程
1、安装Tomcat。
2、编译安装APR。
- 1》解压文件
- tar zxvd apr-1.3.3.tar.gz
- 2》安装
- ./configure --prefix=/u02/apache-tomcat-5.5.27/apr
- make
- make install
- 1》解压文件
- tar zxvd apr-1.3.3.tar.gz
- 2》安装
- ./configure --prefix=/u02/apache-tomcat-5.5.27/apr
- make
- make install
3、编译安装APR UTIL。
- 1》解压文件
- tar zxvd apr-util-1.3.4.tar.gz
- 2》安装
- ./configure --prefix=/u02/apache-tomcat-5.5.27/apr --with-apr=/u02/apache-tomcat-5.5.27/apr
- make
- make install
- 1》解压文件
- tar zxvd apr-util-1.3.4.tar.gz
- 2》安装
- ./configure --prefix=/u02/apache-tomcat-5.5.27/apr --with-apr=/u02/apache-tomcat-5.5.27/apr
- make
- make install
4、编译安装Native。
- 1》解压文件
- tar zxvd tomcat-native-1.1.16-src.tar.gz
- 2》安装
- ./configure --prefix=/u02/apache-tomcat-5.5.27/apr --with-apr=/u02/apache-tomcat-5.5.27/apr --with-java-home=/u02/jdk1.5.0_16
- make
- make install
- 1》解压文件
- tar zxvd tomcat-native-1.1.16-src.tar.gz
- 2》安装
- ./configure --prefix=/u02/apache-tomcat-5.5.27/apr --with-apr=/u02/apache-tomcat-5.5.27/apr --with-java-home=/u02/jdk1.5.0_16
- make
- make install
5、修改Tomcat的启动参数。
打到Tomca t安装目录下 bin/catalina.sh 文件,找到如下内容:
- # Get standard environment variables
- 在其下面添加一行:
- JAVA_OPTS="-Djava.library.path=/u02/apache-tomcat-5.5.27/apr/lib"
- # Get standard environment variables
- 在其下面添加一行:
- JAVA_OPTS="-Djava.library.path=/u02/apache-tomcat-5.5.27/apr/lib"
6、验证。
进入Tomcat的bin目录,执行:
- root@linux:~/apache-tomcat-5.5.27/bin> ./startup.sh
- Using CATALINA_BASE: /u02/apache-tomcat-5.5.27
- Using CATALINA_HOME: /u02/apache-tomcat-5.5.27
- Using CATALINA_TMPDIR: /u02/apache-tomcat-5.5.27/temp
- Using JRE_HOME: /u02/jdk1.5.0_16/jre
- root@linux:~/apache-tomcat-5.5.27/bin> ./startup.sh
- Using CATALINA_BASE: /u02/apache-tomcat-5.5.27
- Using CATALINA_HOME: /u02/apache-tomcat-5.5.27
- Using CATALINA_TMPDIR: /u02/apache-tomcat-5.5.27/temp
- Using JRE_HOME: /u02/jdk1.5.0_16/jre
进入Tomcat的logs目录,打开 catalina.out 文件,可以看到控制台输出的日志如下:
- [b]Apr 17, 2009 11:16:53 AM org.apache.coyote.http11.Http11AprProtocol init[/b]
- INFO: Initializing Coyote HTTP/1.1 on http-9090
- Apr 17, 2009 11:16:53 AM org.apache.coyote.ajp.AjpAprProtocol init
- INFO: Initializing Coyote AJP/1.3 on ajp-8009
- Apr 17, 2009 11:16:53 AM org.apache.catalina.startup.Catalina load
- INFO: Initialization processed in 2160 ms
- Apr 17, 2009 11:16:53 AM org.apache.catalina.core.StandardService start
- INFO: Starting service Catalina
- Apr 17, 2009 11:16:53 AM org.apache.catalina.core.StandardEngine start
- INFO: Starting Servlet Engine: Apache Tomcat/5.5.27
- Apr 17, 2009 11:16:53 AM org.apache.catalina.core.StandardHost start
- INFO: XML validation disabled
- Apr 17, 2009 11:16:57 AM org.apache.coyote.http11.Http11AprProtocol start
- INFO: Starting Coyote HTTP/1.1 on http-9090
- Apr 17, 2009 11:16:58 AM org.apache.coyote.ajp.AjpAprProtocol start
- INFO: Starting Coyote AJP/1.3 on ajp-8009
- Apr 17, 2009 11:16:58 AM org.apache.catalina.storeconfig.StoreLoader load
- INFO: Find registry server-registry.xml at classpath resource
- Apr 17, 2009 11:16:58 AM org.apache.catalina.startup.Catalina start
- INFO: Server startup in 5236 ms
- [b]Apr 17, 2009 11:16:53 AM org.apache.coyote.http11.Http11AprProtocol init[/b]
- INFO: Initializing Coyote HTTP/1.1 on http-9090
- Apr 17, 2009 11:16:53 AM org.apache.coyote.ajp.AjpAprProtocol init
- INFO: Initializing Coyote AJP/1.3 on ajp-8009
- Apr 17, 2009 11:16:53 AM org.apache.catalina.startup.Catalina load
- INFO: Initialization processed in 2160 ms
- Apr 17, 2009 11:16:53 AM org.apache.catalina.core.StandardService start
- INFO: Starting service Catalina
- Apr 17, 2009 11:16:53 AM org.apache.catalina.core.StandardEngine start
- INFO: Starting Servlet Engine: Apache Tomcat/5.5.27
- Apr 17, 2009 11:16:53 AM org.apache.catalina.core.StandardHost start
- INFO: XML validation disabled
- Apr 17, 2009 11:16:57 AM org.apache.coyote.http11.Http11AprProtocol start
- INFO: Starting Coyote HTTP/1.1 on http-9090
- Apr 17, 2009 11:16:58 AM org.apache.coyote.ajp.AjpAprProtocol start
- INFO: Starting Coyote AJP/1.3 on ajp-8009
- Apr 17, 2009 11:16:58 AM org.apache.catalina.storeconfig.StoreLoader load
- INFO: Find registry server-registry.xml at classpath resource
- Apr 17, 2009 11:16:58 AM org.apache.catalina.startup.Catalina start
- INFO: Server startup in 5236 ms
注意上面用粗体标识的部分,说明APR应用成功。
TOMCAT_HOME/bin/catalina.sh
添加一行:JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"
问题解决(可能为调用JAR包过多原因)下面是网上看到一些设置
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "
当在对其进行并发测试时,基本上30个USER上去就当机了,还要修改默认连接数设置:以下红色四行TOMCAT6中好相没有,手工加上就可以了,基本上可以解决连接数过大引起的死机。具体数值可跟据实际情况设置
<Connector port="80" protocol="HTTP/1.1"
maxThreads="600"
minSpareThreads="100"
maxSpareThreads="500"
acceptCount="700"
connectionTimeout="20000" enableLookups="false" //dns关闭
redirectPort="8443" URIEncoding="UTF-8"
/>
这样设置以后,基本上没有再当机过。。。。。
maxThreads="600" ///最大线程数
minSpareThreads="100"///初始化时创建的线程数
maxSpareThreads="500"///一旦创建的线程超过这个值,Tomcat就会关闭不再需要
的socket线程。
acceptCount="700"//指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理
启动时候报错:
解决[SetAllPropertiesRule]{Server/Service/Connector} Setting property 'maxTheads' to '500' did not find a matching property.
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'maxTheads' to '500' did not find a matching property.
2010-7-4 20:49:35 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'minSpareTheads' to '100' did not find a matching property.
2010-7-4 20:49:35 org.apache.catalina.startup.SetAllPropertiesRule begin
警告: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'maxSpareTheads' to '300' did not find a matching property.
但是访问应用程序正常。
通过网上搜索,具体解决方法如下:
server.xml中的配置HTTPS的那部分Connector代码
将protocol参数由"HTTP/1.1"改成"org.apache.coyote.http11.Http11Protocol",重新启动Tomcat,搞定!
根据Tomcat官方的文档http://tomcat.apache.org/tomcat-6.0-doc/config/http.html,"HTTP/1.1"和"org.apache.coyote.http11.Http11Protocol"是一样的,但是不知道为什么前者会出错而后者就是对的,而且HTTP部分的Connector用的也是"HTTP/1.1"。
加快tomcat编译速度
Java Servlet规范很少使用但最优秀的另一特性是在Web应用程序启动时,指定servlet容器必须允许Web应用程序指向应被预编译的JSP页。
例如,如果想让index.jsp(在Web应用程序根目录中)在Web应用程序启动时就一直被预编译。
则在web.xml文件中可以对该文件增加一个<servlet>标签,如下所示:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>index.jsp</servlet-name>
<jsp-file>/index.jsp</jsp-file>
<load-on-startup>0</load-on-startup>
</servlet>
</wep-app>
随后,Tomcat将在Web应用程序启动时自动为您预编译index.jsp,而恰恰就是对/index.jsp的第一个请求将被映射为该JSP预编译的servlet类文件。
以这种方式在Web应用程序中配置预编译,意味着无论Web客户端是否请求JSP,JSP的所有编译工作都在Web应用程序启动时完成。
以这种方式在web.xml中声明的JSP网页都会被预编译。
这种方法的缺陷在于Web应用程序启动的时间总是较长,因为在Web客户端能访问Web应用程序之前,必须预编译所指定的每个网页。
另外,<load-on-startup>容器标签应包含一个正整数。这是指定预编译顺序的松散方式。
在JSP页上指定的数字越小,则在启动过程中预编译越早。
在部署Web应用程序之后,当第一个Web方式请求每个JSP网页时,以这种方式预编译JSP可以使JSP显得速度较快,但是,在编译时(部署前)编译的JSP运行速度对每个请求都较快,即使是对每个JSP页的第一个请求。
http://www.gootry.com/wangzhuan/article/101006192932/277
该构建文件将找到您所有Web应用程序的JSP文件,并将这些JSP文件编译成servlet类,然后为JSP类创建servlet映射。
您必须将产生的servlet映射放到JSP servlet类中,但很难编写Ant构建文件,以便在构建文件运行时每次都以重复的方式将servlet映射插入到web.xml文件中。
相反,笔者使用了一个XMLentity include文件,从而在构建文件运行时,每次都能使产生的servlet映射文件进入一个新文件,并通过XML entity include机制将servlet映射文件插入到web.xml文件中。
要使用这个文件,必须在Web应用程序的WEB-INF/web.xml文件顶端拥有一条特殊的条目声明,并在web.xml文件内容中要包含servlet映射文件的位置引用这一实体。
<!DOCTYPE jspc-webxml[
<!ENTITY jspc-webxml SYSTEM"jspc-web.xml">
]>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsl:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/
javaee/web-app_2_5.xsd" version="2.5">
<!--在此处包含JspC产生的映射-->
&jspc-webxml;
<!--此处没有产生的web.xml内容-->
确信Web应用程序的web.xml文件顶端自始至终都由内嵌的DTD(即DOCTYPE标签),且在其后含有servlet 2.5 Web应用程序架构声明。
然后,在web.xml文件中要插入已产生的servlet映射的地方,放置实体引用语句&jspc-webxml;。
记住,实体引用开始于“&”符号,然后是实体名,最后是分号(;)。
要使用该构建文件,只要编辑该文件,并在顶端将所有属性设置为所要映射的值,然后按如下方式运行:
\$ ant -f pre-compile-jsps.xml
Buildfile: pre-compile-jsps.xml
generate-jsp-java-src:
[jasper2] Sep 27, 2008 10:47:15 PM org.apache.jasper.xmlparser.MyEntityResolver resolveEntity
[jasper2] SEVERE:Invalid PUBLIC ID:null
[jasper2]Sep 27, 2007 10:47:17 PM org.apache.jasper.JspC processFile
[jasper2] INFO:Built File: /index.jsp
BUILD SUCCESSFUL
Total time: 7 seconds
1 source file to /home/jasonb/myproject/webapp-dirWEB-INF/ classes
BUILD SUCCESSFUL
Total time: 7 seconds
在webapp目录下的所有JSP文件都将被编译成servlet,而且在部署Web应用程序时,JSP网页请求都将被映射成已编译的servlet。
如果您得到了“SEVERE:Invalid PUBLIC ID:null”消息,则忽略它,因为这是一条伪信息。如果要清除已编译的servlet,所产生的Java源码及映射,只要按如下方式执行clean目标文件就可以了:
\% ant -f pre-compile-jsps.xml clean
这个构建文件未处理“在编译之后删除Web应用程序中的所有JSP文件”。笔者不希望您意外地删除了JSP文件,所以专门省去了这条语句。在部署Web应用程序之前。
构建文件会完成这一处理。如果忘记了并意外地把JSP文件遗留在部署的Web应用程序中,那么Tomcat不会对这些JSP文件提供服务,因为web.xml文件显式让Tomcat使用已编译的servlet类予以替代。
示例是一个Ant构建文件,可用于构建时编译Web应用程序的JSP文件。
示例:预编译的jsps.xml
<project name="pre-compile-jsps" default="compile-jsp-servlets">
<!--私有属性-->
<property name="webapp.dir" value="(美元符){basedir}/webapp-dir"/>
<property name="tomcat.home" value="/opt/tomcat"/>
<property name="jspc.pkg.prefix"value="com.mycompany"/>
<property name="jspc.dir.prefix" value="com/myeompany"/>
<!--编译属性-->
<property name="debug" value="on"/>
<property name="debuglevel" value="lines,vars, source"/>
<property name="deprecation" value="on"/>
<property name="e ncoding " value="ISO-8859-1"/>
<property name="optimize" value="off"/>
<property name="build.compiler" value="modern"/>
<property name="source.version" value="1.5"/>
<!--初始化路径-->
<path id="jspc.classpath">
<fileset dir="(美元符){tomcat.home}/bin">
<include name="*.jar"/>
</fileset>
<fileset dir="(美元符){tomcat.home}/server/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="(美元符){tomcat.home}/common/i18n">
<include name="*.jar"/>
</fileset>
<fileset dir="(美元符){tomcat.home}/common/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="(美元符){webapp.dir}/WEB-INF">
<include name="lib/"*.jar"/>
</fileset>
<pathelement location="(美元符){webapp.dir}/WEB-INF/classes"/>
<pathelement location="(美元符){ant.home}/lib/ant.jar"/>
<pathelement location="(美元符){java.home}/.../lib/tools.jar"/>
</path>
<property name="jspc.classpath" refid="jspc.classpath"/>
<!-- =====================================>
<!--从JSP文件产生Java源码和web.xml文件-->
<!--===================================>
<target name="generate-jsp-java-src">
<mkdir dir="(美元符){webapp.dir}/WEB-INF/jspc-src/(美元符){jspc.dir.prefix}"/>
<taskdef classname="org.apache.jasper.JspC" name="jasper2">
<classpath>
<path refid="jspc.classpath"/>
</classpath>
</taskdef>
<touch file="(美元符){webapp.dir}/WEB-INF/jspc-web.xml"/>
<jasper2 uriroot="(美元符){webapp.dir}"
package="(美元符){jspc.pkg.prefix}"
webXmlFragment="(美元符){webapp.dir}/WEB-INF/jspc-web.xml"
outputOir="(美元符){webapp.dir}/WEB-INF/jspc-src/ (美元符){jspc.dir.prefix}"
verbose="1"/>
</target>
<!--=========================================-->
<!--编译JSP servlet并由此产生Java类文件-->
<!--由JspC任务产生的源码-->
<!--==============================-->
<target name="compile-jsp-servlets" depends="generate-jsp-java-src">
<mkdir dir="(美元符){webapp.dir}/WEB-INF/classes"/>
<javac srcdir="(美元符){webapp.dir}/WEB-INF/jspc-src"
destdir="(美元符){webapp.dir}/WEB-INF/classes"
includes="**/*.java"
debug="(美元符){debug}"
debuglevel="(美元符){debuglevel}"
deprecation="(美元符){deprecation"}
encoding="(美元符){encoding}"
optimize="(美元符){optimize}"
source="(美元符){source.version"}
<classpath>
<path refid="jspc.classpath">
</classpath>
</javac>
</target>
<!--============================= -->
<!-- 清除所有预编译的JSP源码、类和jspc-web.xml -->
<!-- ====================================== -->
<target name="clean">
<delete dir="(美元符){webapp.dir}/WEB-INF/jspc-src"/>
<delete dir="(美元符){webapp.dir}/WEB-INF/classes/(美元符){jspc.dir.prefix}"/>
<delete file="(美元符){webapp.dir}/WEB-INF/jspc-web.xml"/>
</target)
</project>
如果将整个Ant build.xml内容放到一个叫做pre-compile-jsps.xml的文件中,就可以在已经拥有的任何build.xml文件旁对其进行测试,如果您愿意,还可以把它合并到build.xml中。
相关推荐
本篇文章将聚焦于Tomcat6的性能优化,特别是关于NIO(非阻塞I/O)的使用以及并发量配置。 首先,让我们探讨一下NIO在Tomcat中的作用。传统的BIO(阻塞I/O)模型中,每个Web客户端的请求都会创建一个独立的线程,当...
#### 小结 通过对 Tomcat 的 JKD OPTS、NIO 配置、线程池及 JVM 参数等关键部分进行细致调整,可以显著提升应用服务器的整体性能。合理的资源配置不仅能够提高应用响应速度,还能够降低资源消耗,提升系统的稳定性和...
在本文中,我们将深入...了解这些原理对于优化Web应用性能、处理会话管理问题以及确保用户安全性至关重要。在实际开发中,合理使用Session能够极大地提升用户体验,但也要注意避免Session过多导致的服务器资源消耗。
在实际操作中,还需要根据具体需求调整负载策略、优化性能,以及监控集群的运行状态。配置完成后,测试Apache和Tomcat的通信,确保所有请求能够正确路由和响应,以确保Web应用的稳定运行。同时,注意定期更新和维护...
小结 Tomcat 中配置 MySQL 数据库连接池可以提高系统的性能和稳定性。使用数据库连接池可以将多个请求共享一个连接,从而提高了系统的性能和稳定性。在配置连接池时,需要根据实际情况进行参数配置,例如 maxActive...
8. **性能优化**:对于大量用户和文件的云盘系统,性能优化是必要的。这可能包括数据库查询优化、缓存策略、负载均衡等技术,以提高系统的响应速度和并发处理能力。 通过这个项目,学习者可以深入理解JavaEE开发...
7. 小结: 总结来说,通过复制关键文件夹并重命名,以及修改server.xml配置文件来部署多个war包在同一个Tomcat实例中是完全可行的。这种部署方式虽然复杂,但它允许IT管理员对服务的隔离性和管理的灵活性进行优化,...
- **安全和性能优化**:可能涉及了Web服务的安全策略,如WS-Security(Web Services Security)和OAuth,以及如何通过缓存、异步处理等方式提高Web服务的性能。 - **测试和调试**:可能提到了使用工具(如cURL, ...
10. **优化技巧**:提高网页性能的技巧,如缓存策略、减少HTTP请求、压缩资源、优化数据库查询等,都是开发者应该掌握的知识。 综上所述,这个压缩包可能包含了ASP编程的实战技巧、HTML基础和JSP的应用示例,对于想...
1.7 本章小结 第二部分 自动内存管理机制 第2章 Java内存区域与内存溢出异常 2.1 概述 2.2 运行时数据区域 2.2.1 程序计数器 2.2.2 Java虚拟机栈 2.2.3 本地方法栈 2.2.4 Java堆 2.2.5 方法区 2.2.6 运行...
数据库规格化与数据仓库 数据库视图 数据库元数据 临时表 约束 静态SQL与动态SQL 准备语句 事务处理与隔离级别 存储过程 触发器 复制 优化基础 小结 第6章 Java数据库...
### 超杰软件系列(JSP进销存)——关键技术知识点解析 #### 一、概述 超杰软件系列(JSP进销存)是一款基于Java Server Pages (JSP...此外,对于一些高级特性,如安全性增强、性能优化等,也需要开发者进一步研究和实践。
第10章hibernate性能优化 208 10.1hibernate事务与并发 208 10.1.1什么是事务 208 10.1.2hibernate中的事务处理 209 10.1.3在hibernate中使用jta事务 210 10.1.4并发控制 211 10.2hibernate缓存 213 10.2.1...
六、本章小结 本章主要介绍了项目的背景、意义,以及国内外研究现状,明确了研究目标和内容。接下来的章节将详细展开系统的设计、实现和性能评估,旨在为敬老院提供一套实用的信息化管理解决方案。 整个系统设计中...
- **本章小结**:强调Jetty的多功能性和灵活性,为后续章节打下基础。 2. **Jetty 初探** - **下载与安装**:提供Jetty的下载地址和简单安装步骤,包括Windows和Linux下的操作。 - **启动与停止**:通过java命令...
#### 1.8 小结 完成了 MyEclipse 6 的安装配置后,即可开始 Java EE 应用程序的开发。 ### 2. 开发第一个 Java 应用程序 #### 2.1 手工编写、编译并运行 Java 程序 - 使用文本编辑器编写 Java 代码。 - 使用...
10. **安全性与优化**:系统可能考虑了权限控制、SQL注入防护、XSS攻击防御等安全措施,同时,通过合理的缓存策略、数据库索引优化、代码性能调优等手段,提升系统的响应速度和并发处理能力。 综上所述,Q_ITOffer....
**小结** Camunda的设计工具能够更好地满足不同用户群体的需求,无论是专业的开发人员还是业务分析师都能轻松上手,而Flowable则更侧重于为开发人员提供服务。 #### 二、数据库支持对比 **2.1 Camunda 支持的...
9. **性能优化**:为了提高系统性能,可能采用了缓存策略、多线程处理、文件流操作等技术。此外,合理的URL设计、资源压缩和合并也是提升用户体验的重要手段。 10. **测试与部署**:项目完成后,需要进行功能测试、...