tomcat是咱们经常使用的web容器,它的性能高低直接影响到应用对外提供服务的能力和用户的体验,因此tomcat的优化相当重要。对于单台tomcat服务器而言,优化主要是两方面:内存优化和配置优化(例如,链接数,线程池,iO等),固然还有使用tomcat原生库。除了这些tomcat自己固有配置优化,还有一些减小占用tomcat链接时间的配置,好比数据压缩。若是单个服务器通过优化后依然没法知足,性能要求,这时服务器集群就是必须的手段了,下面针对这些方面的优化详细介绍。javascript
tomcat用户配置css
优化配置以前,咱们须要配置一个tomcat管理员帐户,来登陆查看Tomcat控制台提升的各类参数。在conf/ tomcat-users.xml下添加用户:html
<role rolename="manager"/> <role rolename="manager-gui"/> <role rolename="admin"/> <role rolename="admin-gui"/> <user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/>
启动tomcat,登陆查看信息:http://127.0.0.1:8080/:java
内存优化linux
主要是针对jvm各个内存大小的分配进行优化,以提升内存的使用率和减小资源变化带来的时间消耗。有关文件:catalina.sh(linux下)或者catalina.bat(window下)。程序员
注意:对于32位操做系统上对jvm的内存有不能超过2G的限制,可是64位系统上没有这个限制。但不少状况下32操做系统上jvm的最大使用内存是不到2G的,2G只是个理想值,根据服务器的配置不一样,可能有些只能用1500M或者1700M。具体支持多少,能够在控制台输入:java -Xmx2089M -version,若是出现Java版本,说明你的jvm内存能够设置到2089M。web
Linux系统中tomcat的启动参数:面试
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 "
Windows系统中tomcat的启动参数:数据库
set 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
这个参数必须加上,由于tomcat默认是以一种叫java –client的模式来运行的,server即意味着你的tomcat是以真实的production的模式在运行的,这也就意味着你的tomcat以server模式运行时将拥有:更大、更高的并发处理能力,更快更强捷的JVM垃圾回收机制等。apache
Xms是JVM初始化时的内存大小;Xmx是jvm的最大内存大小。Xms默认是物理内存的1/64,Xmx默认是物理内存的1/4,建议是物理内存的80%,可是通常咱们会把Xms和Xmx设置同样大,这样在服务器启动时就是最大值能够避免内存膨胀和回落时带来的资源的消耗。特别是回落时会带来cpu的高速运转进行垃圾回收,系统可能会出现几秒甚至几十秒的卡顿现象。
Xmn是年轻代大小。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代通常固定大小为64m,因此增大年轻代后,将会减少年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
是指设定每一个线程的堆栈大小。这个就要依据你的程序,看一个线程 大约须要占用多少内存,可能会有多少线程同时运行等。通常不易设置超过1M,要否则容易出现out ofmemory。
做用如其名(aggressive),启用这个参数,则每当JDK版本升级时,你的JVM都会使用最新加入的优化技术(若是有的话)
启用一个优化了的线程锁,咱们知道在咱们的appserver,每一个http请求就是一个线程,有的请求短有的请求长,就会有请求排队的现象,甚至还会出现线程阻塞,这个优化了的线程锁使得你的appserver内对线程处理自动进行最优调配。
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;在数据量的很大的文件导出时,必定要把这两个值设置上,不然会出现内存溢出的错误。由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。那么,若是是物理内存4GB,那么64分之一就是64MB,这就是PermSize默认值,也就是永生代内存初始大小;四分之一是1024MB,这就是MaxPermSize默认大小。
PermGen space的全称是Permanent Generationspace,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到
PermGenspace中,它和存放类实例(Instance)的Heap区域不一样,GC(GarbageCollection)不会在主程序运行期对PermGenspace进行清理,因此若是你的应用中有很CLASS的话,就极可能出现“java.lang.OutOfMemoryError:PermGen space”错误。
对于WEB项目,jvm加载类时,永久域中的对象急剧增长,从而使jvm不断调整永久域大小,为了不调整),你可使用更多的参数配置。若是你的WEBAPP下都用了大量的第三方jar, 其大小超过了jvm默认的大小,那么就会产生此错误信息了。
在程序代码中不容许有显示的调用”System.gc()”。看到过有两个极品工程中每次在DAO操做结束时手动调用System.gc()一下,以为这样作好像可以解决它们的out ofmemory问题同样,付出的代价就是系统响应时间严重下降,就和我在关于Xms,Xmx里的解释的原理同样,这样去调用GC致使系统的JVM大起大落,性能不到什么地方去哟!
对年轻代采用多线程并行回收,这样收得快。
即CMS gc,这一特性只有jdk1.5即后续版本才具备的功能,它使用的是gc估算触发和heap占用触发。
咱们知道频频繁的GC会造面JVM的大起大落从而影响到系统的效率,所以使用了CMS GC后能够在GC次数增多的状况下,每次GC的响应时间却很短,好比说使用了CMS GC后通过jprofiler的观察,GC被触发次数很是多,而每次GC耗时仅为几毫秒。
设置垃圾最大年龄。若是设置为0的话,则年轻代对象不通过Survivor区,直接进入年老代。对于年老代比较多的应用,能够提升效率。若是将此值设置为一个较大值,则年轻代对象会在Survivor区进行屡次复制,这样能够增长对象再年轻代的存活时间,增长在年轻代即被回收的几率。
这个值的设置是根据本地的jprofiler监控后获得的一个理想的值,不能一律而论原搬照抄。
在使用UseParNewGC 的状况下, 尽可能减小 mark 的时间
在使用concurrent gc 的状况下, 防止 memoryfragmention, 对live object 进行整理, 使 memory 碎片减小。
指定 Java heap的分页页面大小
get,set 方法转成本地代码
指示只有在 oldgeneration 在使用了初始化的比例后concurrent collector 启动收集
CMSInitiatingOccupancyFraction,这个参数设置有很大技巧,基本上知足(Xmx-Xmn)*(100- CMSInitiatingOccupancyFraction)/100>=Xmn就不会出现promotion failed。在个人应用中Xmx是6000,Xmn是512,那么Xmx-Xmn是5488兆,也就是年老代有5488 兆,CMSInitiatingOccupancyFraction=90说明年老代到90%满的时候开始执行对年老代的并发垃圾回收(CMS),这时还 剩10%的空间是5488*10%=548兆,因此即便Xmn(也就是年轻代共512兆)里全部对象都搬到年老代里,548兆的空间也足够了,因此只要满 足上面的公式,就不会出现垃圾回收时的promotion failed;
所以这个参数的设置必须与Xmn关联在一块儿。
这个参数通常咱们都是放在最后使用的,这全参数的做用是这样的,有时咱们会在咱们的J2EE工程中使用一些图表工具如:jfreechart,用于在web网页输出GIF/JPG等流,在winodws环境下,通常咱们的app server在输出图形时不会碰到什么问题,可是在linux/unix环境下常常会碰到一个exception致使你在winodws开发环境下图片显示的好好但是在linux/unix下却显示不出来,所以加上这个参数以避免避这样的状况出现。
上述这样的配置,基本上能够达到:
配置优化
主要是优化conf/server.xml文件中相关配置参数。
链接器优化
这里主要是优化connector标签中的相关参数,用于处理访问的请求;固然此标签中也能够设置线程的相关参数,可是为了更好的性能通常咱们使用外部的线程池,这样有利于线程的复用,以减小线程的建立和销毁带来的资源消耗;另外,咱们也能够修改tomcat的运行模式:BIO,NIO,AIO(NIO2),APR.
AJP链接器:
用于将Apache与Tomcat集成在一块儿,当Apache接收到动态内容请求时,经过在配置中指定的端口号将请求发送给在此端口号上监听的AJP链接器组件。
属性:
backlog:当全部可能的请求处理线程都在使用时,队列中排队的请求最大数目。默认为10,当队列已满,任何请求都将被拒绝
maxSpareThread:容许存在空闲线程的最大数目,默认值为50
maxThread:最大线程数,默认值为200
minSpareThreads:设当链接器第一次启动时建立线程的数目,确保至少有这么多的空闲线程可用,默认值为4
port:服务端套接字的TCP端口号,默认值为8089(必须)
topNoDelay:为true时,能够提升性能,默认值为true
soTimeout:超时值
例:
<!—Define an AJP1.3 Connector on port 8089-->
<Connector port=”8089” enableLookups=”false” redirectPort=”8443” protocol=”AJP/1.3” />
AJPv13协议是面向包的。WEB服务器和Servlet容器经过TCP链接来交互;为了节省SOCKET建立的昂贵代价,WEB服务器会尝试维护一个永久TCP链接到servlet容器,而且在多个请求和响应周期过程会重用链接。咱们通常是使用Nginx+tomcat的架构,因此用不着AJP协议,因此把AJP链接器禁用。
2.Connector标签常见参数的配置:
<Connector port="8080" protocol="HTTP/1.1"
//编码格式
URIEncoding="UTF-8"
//线程配置
maxThreads="1000" maxProcessors="1000" minProcessors="5" minSpareThreads="100" maxSpareThreads="1000
//链接数配置
maxConnections="1000"
connectionTimeout="20000" acceptCount="1000"
//是否关闭DNS的反响查询 false:关闭,true:开启
enableLookups="false"
//是否保持长时间链接,false:关闭,ture:开启
disableUploadTimeout="true"
//是否开启对url进行校验的配置 ,false:关闭,true:开启
useURIValidationHack="false"
//启用压缩的配置
compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
//post请求提交最大大小
maxPostSize="10485760"
maxHttpHeaderSize="8192"
tcpNoDelay="true"
acceptorThreadCount="8"
redirectPort="8443" />
固然Connector标签中的参数还有不少,这是只是常见的参数设置;而且这些中的参数也不必定都要设置,须要根据项目的具体状况去设置。
最后不要忘了把8443端口的地方也加上一样的配置,由于若是咱们走https协议的话,咱们将会用到8443端口这个段的配置:
<!--enable tomcat ssl--> <Connector port="8443" protocol="HTTP/1.1" URIEncoding="UTF-8" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000"acceptCount="300" maxThreads="300"
maxProcessors="1000" minProcessors="5" useURIValidationHack="false" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="d:/tomcat2/conf/shnlap93.jks" keystorePass="aaaaaa" />
线程池优化
在tomcat中每个用户请求都是一个线程,因此可使用线程池提升性能.在介绍Connector标签中咱们看到已经有线程的相关参数的设置,为何还要有线程池?其实这个和Java中的线程池是一个道理,使用线程池可使多链接公用线程,避免线程的频繁的建立和销毁带来的资源消耗。
引入线程池的方法,使用Connector标签中的executor的属性,将其值设置为Executor标签的name的值。例如:
<Connector port="8066" executor="tomcatThreadPool" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" enableLookups="false" maxPostSize="10485760" URIEncoding="UTF-8" useBodyEncodingForURI="true"
acceptCount="100" acceptorThreadCount="2" disableUploadTimeout="true" maxConnections="10000" SSLEnabled="false" />
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="1000" minSpareThreads="100" maxIdleTime="60000" maxQueueSize="Integer.MAX_VALUE" prestartminSpareThreads="false" threadPriority="5" className="org.apache.catalina.core.StandardThreadExecutor"/>
Executor线程池的参数介绍:
优化IO模式
tomcat中io模式通常分为分别为BIO(阻塞型IO),NIO,NIO2和APR。区别:
其实从上面的分析咱们并不能简单的认为BIO的性能就必定不如 NIO,这几种类型 Connector之间并无明显的性能区别,但它们之间实现流程和原理不一样,因此它们的选择是须要根据应用的类型来决定的。
修改io模式:
<Connector connectionTimeout="20000" port="8066" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8448"/>
从上面代码能够看出修改io模式其实就是修改connector标签中的protocol属性的值,其余几种io模式对应的值以下:
//BIO protocol="HTTP/1.1" //NIO protocol="org.apache.coyote.http11.Http11NioProtocol" //NIO2 protocol="org.apache.coyote.http11.Http11Nio2Protocol" //APR protocol="org.apache.coyote.http11.Http11AprProtocol"
监听器Listener配置
另外一个影响Tomcat 性能的因素是内存泄露。Server标签中能够配置多个Listener,其中 JreMemoryLeakPreventionListener是用来预防JRE内存泄漏。此Listener只需在Server标签中配置便可,默认状况下无需配置,已经添加在 Server中
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
压缩
压缩也是tomcat性能优化比较中要的一部分,主要是经过connector标签中的下面几个参数来实现的
compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
HTTP 压缩能够大大提升浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML,CSS,Javascript , Text ,它能够节省40%左右的流量。更为重要的是,它能够对动态生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩,压缩效率惊人。
数据库性能调优
Tomcat性能在等待数据库查询被执行期间会下降。现在大多数应用程序都是使用可能包含“命名查询”的关系型数据库。若是是那样的话,Tomcat会在启动时默认加载命名查询,这个可能会提高性能。另外一件重要事是确保全部数据库链接正确地关闭。给数据库链接池设置正确值也是十分重要的。我所说的值是指Resource要素的最大空闲数(maxIdle),最大链接数(maxActive),最大创建链接等待时间(maxWait)属性的值。由于配置依赖与应用要求,我也不能在本文指定正确的值。你能够经过调用数据库性能测试来找到正确的值。固然数据库调优自己就是一个功能好大且至关复杂的工做,后面咱们会专门研究如何进行数据调优!
tomcat原生库
Tomcat的原生库基于Apache可移植运行时(Apache Portable Runtime简称APR),给程序员提供了超强的扩展性和性能,在产品运做中帮助融合原生的服务器技术以展示最佳的性能。想知道安装说明的朋友请参考Tomcat Native Library – (APR) Installation。
其余优化措施
学习连接