Tomcat性能调优

tomcat/bin/setenv.sh 用于tomcat启动的参数配置(当前目录下,会在tomcat启动时自动调用)

cat tomcat/bin/catalina.sh

if [ -r "$SETENVPATH/bin/setenv.sh" ]; then
  . "$SETENVPATH/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
  . "$CATALINA_HOME/bin/setenv.sh"
fi

cat tomcat/bin/setenv.sh

#!/bin/sh
export CATALINA_OPTS="-Xmx350M -Xms350M -XX:PermSize=64M -XX:MaxPermSize=64m -XX:+UseParallelGC -Dlog4j.configuration=file:///home/www/config/java/scheduler_log4j.xml"
export CATALINA_PID="$CATALINA_BASE/logs/catalina.pid"

............

--------------------------------------------------------------------------

1、Apache Tomcat6 中支持了Java语言的特性 NIO( New I/O),使用NIO在服务器端会有更好的性能,加强服务器端对并发处理的性能。但是,在tomcat6在默认的配置选项中是没有把NIO功能打开。在tomcat的配置文件conf/server.xml中,找到以下配置:

        <Connector port="8080" protocol="HTTP/1.1" 
       connectionTimeout="20000" 
        redirectPort="8443" />

  在控制台的启动信息里看见,默认状态下 没有被打开nio配置,启动时的信息,如下:

      2010-2-1 12:59:40 org.apache.coyote.http11.Http11Protocol init
  信息: Initializing Coyote HTTP/1.1 on http-8080
  2010-2-1 12:59:40 org.apache.catalina.startup.Catalina load 

  修改成支持NIO的类型,配置如下 :

  <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol "
               connectionTimeout="20000"
               redirectPort="8443" />

  进行测试,被打开nio配置,启动时的信息,如下:
  2010-2-1 13:01:01 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector 
  信息: Using a shared selector for servlet write/read 
  2010-2-1 13:01:01 org.apache.coyote.http11.Http11NioProtocol init 
  信息: Initializing Coyote HTTP/1.1 on http-8080

2、JAVA虚拟机性能优化

  Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个java虚拟机。可以根据自己的需要选择不同的操作系统和对应的JDK版本(只要是符合Sun发布的Java规范的),推荐使用Sun公司发布的JDK。确保所使用的版本是最新的,因为Sun公司和其它一些公司一直在为提高性能而对java虚拟机做一些升级改进。一些报告显示JDK1.4在性能上比JDK1.3提高了将近10%到20%。

  可以给Java虚拟机设置使用的内存,但是如果选择不对的话,虚拟机不会补偿。可通过命令行的方式改变虚拟机使用内存的大小。

  -Xms<size> 表示JVM初始化堆的大小,-Xmx<size>表示JVM堆的最大值。一般建议堆的最大值设置为可用内存的最大值的80%,并将-Xms和-Xmx选项设置为相同。

   堆内存分配
    JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等避免在每次GC 后调整堆的大小。
    非堆内存分配
    JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

    JVM内存限制(最大值)
    首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。
      JAVA_OPTS="-server -Xms2048M -Xmx2048M -Xss256k -XX:+AggressiveOpts -XX:+UseParallelGC-XX:+UseBiasedLocking"
      配置示例:JAVA_OPTS="-server -XX:PermSize=128M -XX:MaxPermSize=256M -XX:MaxNewSize=256M"
                    JAVA_OPTS="$JAVA_OPTS -Xms2048M -Xmx2048M -Xss128K"

  修改apache-tomcat-6.0.18incatalina.bat(catalina.sh)配置文件为以下:

  set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=128M -XX:MaxPermSize=256m
  这一句加在
  rem ---------------------------------------------------------------------------
  与
  rem Guess CATALINA_HOME if not defined
  之间的位置,不要加到那些if里面去了,否则不一定会生效。

3、停用DNS查询

  当web应用程序向要记录客户端的信息时,它也会记录客户端的IP地址或者通过域名服务器查找机器名转换为IP地址。
  DNS查询需要占用网络,并且包括可能从很多很远的服务器或者不起作用的服务器上去获取对应的IP的过程,这样会消耗一定的时间。
  修改server.xml文件中的enableLookups参数值: enableLookups="false"           

  <Connector 
    port="8887" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" 
    enableLookups="false" redirectPort="8443" acceptCount="100" 
    debug="0" connectionTimeout="20000" 
    disableUploadTimeout="true" /> 
  加上enableLookups="false";这样就不使用DNS查询,也不会有延迟了。除非需要所有连接到服务器的HTTP客户端的完整主机名称。
  注:Connector的enableLookups性属的意义是:调用request.getRemoteHost()是否会通过DNS查询来取得远处客户端的真正主机名称。true表示会查询,false表示以字符串格式传回客户端的IP地址。默认值是:true。

4、调整线程的数目

  通过应用程序的连接器(Connector)进行性能控制的的参数是创建的处理请求的线程数。
  Tomcat使用线程池加速响应速度来处理请求。在Java中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同的地址空间。多线程帮助程序员写出CPU最大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。
  示例如下:
  <Connector port="80" protocol="HTTP/1.1"
    maxThreads="600" 最多运行线程数,默认值为200  
    minSpareThreads="100" 初始化创建的线程数
    maxSpareThreads="500"最多能创建的线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要socket线程.
    acceptCount="700" 指定当所有可以使用的处理请求的线程数都被使用时可以放到处理队列中的请求数,超过这个数的请求将不予处理,默认值为100
    connectionTimeout="20000"
    enableLookups="false"
    redirectPort="8443" />

5、Tomcat6线程池(Executor Thread pool)的配置 
  第一步,打开共享的线程池
        <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" 
            maxThreads="1000" minSpareThreads="50" maxIdleTime="600000"/>
        name 这个是线程池的名字,必须唯一,后面的配置里要用到这个东西 
        namePrefix 线程的名字前缀,用来标记线程名字,每个线程就用这个前缀加上线程编号了,比如 
          catalina-exec-1 
          catalina-exec-2 
      maxThreads 允许的最大线程池里的线程数量,默认是200,大的并发应该设置的高一些,只是限制而已,不占用资源。
      minSpareThreads 最小的保持活跃的线程数量,默认是25.
      要根据负载情况自行调整了:太小影响反应速度,太大占用资源。 
      maxIdleTime 超过最小活跃线程数量的线程,空闲时间超过这个设置后,会被关闭,默认是1分钟。 
      threadPriority 线程的等级。默认是Thread.NORM_PRIORITY 
  第二步 在Connector里指定使用共享线程池
      <Connector port="8009" ... maxThreads="5000" executor="tomcatThreadPool" ... />
        注意,一旦使用了线程池,则其它的线程属性,比如 maxThreads等将被忽略

6.在tomcat中设置session过期时间
    在confweb.xml中通过参数指定:
    <session-config>   
        <session-timeout>180</session-timeout>     
    </session-config> 单位为分钟。

tomcat容器调优详参:

vim $CATALINA_HOME/conf/server.xml

...

<Connector port="8080" protocol="HTTP/1.1"

          URIEncoding="UTF-8"  minSpareThreads="25" maxSpareThreads="75"

          enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000"

          acceptCount="500"  maxThreads="300"

          useURIValidationHack="false"

          compression="on" compressionMinSize="2048"

          compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"

          redirectPort="8443"

/>

...

【注释】

URIEncoding:URI编码,这里参数是UTF-8,很容易理解,即支持中文域名

minSpareThreads:最小空闲线程,即tomcat可以保留的最小线程

maxSpareThreads:最大空闲进程,如果超出这个参数,则会被回收

(这两个参数根据实际环境而定,如果每天都有一个并发爆发期,则最好min设置的大一些)

enableLookups:是否开启域名解析,这个一般都禁止,域名解析影响性能

disableUploadTimeout:

connectionTimeout:连接超时时间,单位是ms,根据程序性能决定

maxThreads:同一时刻可以接收的最大请求,即并发量

acceptCount:若超出maxThreads,则超出部分不能超过此参数值,若超过,则拒绝

useURIValidationHack:设置为false可以减少tomcat对一些url的不必要的检查从而减省开销【不明觉厉】

compression:是否启用压缩,肯定启用了

compressionMinSize:压缩文件大小下限,单位字节

compressableMimeType:压缩文件的Mime类型

redirectPort:重定向(因此若为443https,则8443 connector也应该加入以上参数)


jvm调优

vim $CATALINA_HOME/bin/catalina.sh

...

export JAVA_OPTS="-server -Xms8192M -Xmx8192M -Xmn3072M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=256M -XX:MaxPermSize=4096M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC  -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m  -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true"

...

【注释信息】

jvm调优其实就是在catalina启动时临时加上JAVA_OPTS变量值的。

-server:意思就是将tomcat改为生产模式,这个看网上说明,不加的话,就如同实验环境一样。因此,必加参数

-Xms:jvm最小堆内存

-Xmx:jvm最大堆内存

这两个值的差值叫做保留内存,不过建议最好设置的一样,即最小内存随同最大内存,之所以这么设置是因为,内存回收的时候,也是需要消耗cpu的,如果此时突然并发又来了,而tomcat却在回收内存,那么就不爽了

-Xmn:新生态内存,这个官方建议是jvm堆内存的3/8,堆内存=新生内存+老年内存+持久内存

-Xss:设定每个线程的堆栈大小

-XX:+AggressiveOpts:作用如其名(aggressive),启用这个参数,则每当JDK版本升级时,你的JVM都会使用最新加入的优化技术

-XX:+UseBiasedLocking:启用一个优化了的线程锁,我们知道在我们的appserver,每个http请求就是一个线程,有的请求短有的请求长,就会有请求排队的现象,甚至还会出现线程阻塞,这个优化了的线程锁使得你的appserver内对线程处理自动进行最优调配。

-XX:PermSize:持久态最小内存,默认为物理内存大小的1/64

-XX:MaxPermSize:持久态最大内存,默认为物理内存大小的1/4

-XX:+DisableExplicitGC:在程序代码中不允许有显示的调用”System.gc()”,【不明觉厉】

-XX:MaxTenuringThreshold:设置对象在年轻态停留的时间,时间越长,被回收概率越大,若为0,则直接转到老年态

-XX:+UseConcMarkSweepGC:CMS gc,这一特性只有jdk1.5即后续版本才具有的功能,它使用的是gc估算触发和heap占用触发。

我们知道频频繁的GC会造面JVM的大起大落从而影响到系统的效率,因此使用了CMS GC后可以在GC次数增多的情况下,每次GC的响应时间却很短,比如说使用了CMS GC后经过jprofiler的观察,GC被触发次数非常多,而每次GC耗时仅为几毫秒。【不明觉厉】

-XX:+UseParNewGC:年轻代采用多线程并行回收,加速回收  

 -XX:+CMSParallelRemarkEnabled:在使用UseParNewGC 的情况下, 尽量减少 mark 的时间【不明觉厉】

-XX:+UseCMSCompactAtFullCollection:在使用concurrent gc 的情况下, 防止 memoryfragmention, 对live object 进行整理, 使 memory 碎片减少【不知道啥意思】

-XX:LargePageSizeInBytes:指定 Java heap的分页页面大小

-XX:+UseFastAccessorMethods:get,set 方法转成本地代码【不知道啥意思】

-XX:+UseCMSInitiatingOccupancyOnly:指示只有在 oldgeneration 在使用了初始化的比例后concurrent collector 启动收集【不知道啥意思】

-Djava.awt.headless=true":这个参数一般我们都是放在最后使用的,这全参数的作用是这样的,有时我们会在我们的J2EE工程中使用一些图表工具如:jfreechart,用于在 web网页输出GIF/JPG等流,在winodws环境下,一般我们的app server在输出图形时不会碰到什么问题,但是在linux/unix环境下经常会碰到一个exception导致你在winodws开发环境下图片显 示的好好可是在linux/unix下却显示不出来,因此加上这个参数以免避这样的情况出现。【虽然知道结果,就是不知道因在何处】

server.xml示例文件:

复制代码
<?xml version='1.0' encoding='utf-8'?>
<Server port="8123" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="2000" minSpareThreads="500"/>
    <!--
    <Connector port="9095" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000"
               maxThreads="512"
           minSpareThreads="25"
           acceptCount="512"
           disableUploadTimeout="true"
           enableLookups="false"
           URIEncoding="UTF-8"
               redirectPort="9444" />
    -->
    <Connector port="8080"
        protocol="org.apache.coyote.http11.Http11NioProtocol"
        executor="tomcatThreadPool"
        compression="on"
        compressionMinSize="2048"
        enableLookups="false"
        redirectPort="8443"
        acceptCount="4000"
        connectionTimeout="20000"
        disableUploadTimeout="true" URIEncoding="UTF-8" useBodyEncodingForURI="true" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define a SSL HTTP/1.1 Connector on port 8443
         This connector uses the JSSE configuration, when using APR, the
         connector should be using the OpenSSL style configuration
         described in the APR documentation -->
    <!--
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />


    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" 
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b request_time %D msec %T status %s" resolveHosts="false"/>-->

      </Host>
    </Engine>
  </Service>
</Server>
复制代码
原文地址:https://www.cnblogs.com/exmyth/p/11901856.html