tomcat 优化实记

好记性不如烂笔头,以下是 tomcat 无脑优化

1.内存设置(VM参数调优)
(1). Windows环境下,是tomcat解压版(执行startup.bat启动tomcat) 

解决办法:
修改“%TOMCAT_HOME%\bin\catalina.bat”文件,

在文件开头增加如下设置:

1 set JAVA_OPTS=-Xms512m -Xmx512m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=512m

备注:一定加在catalina.bat最前面。

 (2).Linux环境下

解决办法:
修改“%TOMCAT_HOME%\bin\catalina.sh”文件,

在文件开头增加如下设置:

 

JAVA_OPTS="-XX:PermSize=64M -XX:MaxPermSize=128m -Xms512m -Xmx1024m -Duser.timezone=Asia/Shanghai"


注意:前后二者区别,有无set,有无双引号。


各参数详解:

-Xms:设置JVM初始内存大小(默认是物理内存的1/64)
-Xmx:设置JVM可以使用的最大内存(默认是物理内存的1/4,建议:物理内存80%)
-Xmn:设置JVM最小内存(128-256m就够了,一般不设置)

默认空余堆内存小于 40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、 -Xmx相等以避免在每次GC 后调整堆的大小。
在较大型的应用项目中,默认的内存是不够的,有可能导致系统无法运行。

常见的问题是报Tomcat内存溢出错误

“java.lang.OutOfMemoryError: Java heap space”,

从而导致客户端显示500错误。

-XX:PermSize :为JVM启动时Perm的内存大小
-XX:MaxPermSize :为最大可占用的Perm内存大小(默认为32M)
-XX:MaxNewSize,默认为16M

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,

所以如果你的应用中有很CLASS的话,

就很可能出现“java.lang.OutOfMemoryError: PermGen space”错误。

对于WEB项目,jvm加载类时,永久域中的对象急剧增加,从而使jvm不断调整永久域大小,为了避免调整),你可以使用更多的参数配置。如果你的WEB APP下都用了大量的第三方jar,

其大小超过了jvm默认的大小,那么就会产生此错误信息了。
其它参数:

-XX:NewSize :默认为2M,此值设大可调大新对象区,减少Full GC次数
-XX:NewRatio :改变新旧空间的比例,意思是新空间的尺寸是旧空间的1/8(默认为8)
-XX:SurvivorRatio :改变Eden对象空间和残存空间的尺寸比例,意思是Eden对象空间的尺寸比残存空间大survivorRatio+2倍(缺省值是10)
-XX:userParNewGC 可用来设置并行收集【多CPU】
-XX:ParallelGCThreads 可用来增加并行度【多CPU】
-XXUseParallelGC 设置后可以使用并行清除收集器【多CPU】

 

2.修改tomcat让其支持NIO

 


修改前: 

 

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

 


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

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

 

3.并发数设置
默认的tomcat配置,并发测试时,可能30个USER上去就当机了。
添加

maxThreads="600" //最大线程数
minSpareThreads="100" //初始化时创建的线程数
maxSpareThreads="500" //一旦线程超过这个值,Tomcat会关闭不需要的socket线程
acceptCount="700"//指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理
connectionTimeout="20000"
redirectPort="8443" />

或者

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"  maxThreads="500"        minSpareThreads="70" maxSpareThreads="500" acceptCount="700"    maxIdleTime="60000" />

 

<Connector executor="tomcatThreadPool" port="9091" protocol="HTTP/1.1"  connectionTimeout="60000" keepAliveTimeout="15000" maxKeepAliveRequests="1"  redirectPort="8443" />

如果你的是使用 AJP 协议,集成的集群那么你还需要

<Connector port="13000" protocol="AJP/1.3"  executor="tomcatThreadPool"
connectionTimeout="30000" redirectPort="8443" />

这里最好使用这种方式,让2个端口使用同一个线程池

 

4.Java虚拟机调优


应该选择SUN的JVM,在满足项目需要的前提下,尽量选用版本较高的JVM,一般来说高版本产品在速度和效率上比低版本会有改进。 JDK1.4比JDK1.3性能提高了近10%-20%,JDK1.5比JDK1.4性能提高25%-75%。

 

5.禁用DNS查询


server.xml 设置enableLookups="false":

enableLookups="false" redirectPort="8443" URIEncoding="UTF-8" acceptCount="1000" />

 


 当web应用程序向要记录客户端的信息时,它也会记录客户端的IP地址或者通过域名服务器查找机器名转换为IP地址。DNS查询需要占用网络, 并且包括可能从很多很远的服务器或者不起作用的服务器上去获取对应的IP的过程,这样会消耗一定的时间。为了消除DNS查询对性能的影响我们可以关闭 DNS查询,

方式是修改server.xml文件中的enableLookups参数值为false。

 

6.设置解决乱码问题

URIEncoding="UTF-8" />

 

Tomacat7启动报错如下(Jar包冲突):

 

解决方法为:在Tomacat7的context.xml文件里的<Context>中加上(使用本地Jar包)

java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addFilter

<Loader delegate="true" />

 

我的tomcat 配置conf/server.xml

<?xml version='1.0' encoding='utf-8'?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 -->
<Server port="9001" shutdown="SHUTDOWN">
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <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>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <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="150" minSpareThreads="4"/>
    -->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"  maxThreads="500"        minSpareThreads="70" maxSpareThreads="500" acceptCount="700"    maxIdleTime="60000" />

    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL HTTP/1.1 Connector on port 8080
   
    <Connector port="9091" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

    <Connector port="9091" protocol="HTTP/1.1" maxThreads="700"        minSpareThreads="90" maxSpareThreads="500" acceptCount="900"
    connectionTimeout="30000" redirectPort="8443" />
 -->
    <Connector executor="tomcatThreadPool" port="9091" protocol="HTTP/1.1"  connectionTimeout="60000" keepAliveTimeout="15000" maxKeepAliveRequests="1"  redirectPort="8443" />

    <!-- 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="11000" protocol="AJP/1.3" redirectPort="8443" />-->

<Connector port="11000" protocol="AJP/1.3"  executor="tomcatThreadPool"
connectionTimeout="30000" 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" jvmRoute="tomcat3">

      <!--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"/>

    <!-- 
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"   
channelSendOptions="8" >          
<Manager className="org.apache.catalina.ha.session.DeltaManager"   
expireSessionsOnShutdown="false"   
notifyListenersOnReplication="true" />  

<Channel className="org.apache.catalina.tribes.group.GroupChannel" >  
<Membership className="org.apache.catalina.tribes.membership.McastService"   
address="228.0.0.4"   
port="45564"   
frequency="500"   
dropTime="3000" />  
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"   
address="auto"   
port="4000"   
   
selectorTimeout="5000"   
maxThreads="6" />  -->
<!-- timeout="60000" 
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter" >  
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"  />  
</Sender>  
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector" />  
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" />  
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor" />  
</Channel>  

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter="" />  
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" />  

<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"   
tempDir="/tmp/war-temp/"   
deployDir="/tmp/war-deploy/"   
watchDir="/tmp/war-listen/"   
watchEnabled="false" />  

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;" />  


<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" />  
</Cluster>      
-->  
  

      <!-- 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"
            xmlValidation="false" xmlNamespaceAware="false">
    <Context path="" docBase="E:\Clusters\static\" reloadable="true" crossContext="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" />

      </Host>
    </Engine>
  </Service>
</Server>

 



你可能感兴趣的:(tomcat 优化实记)