码迷,mamicode.com
首页 > 其他好文 > 详细

tomcat配置调优与安全总结

时间:2015-07-10 19:22:00      阅读:473      评论:0      收藏:0      [点我收藏+]

标签:tomcat 配置 调优 安全 监控

tomcat配置调优与安全总结

    作为运维,避免不了与tomcat打交道,然而作者发现网络上关于tomcat配置和调优安全的文章非常散,通过参考各位大神的相关技术文档,根据作者对tomcat的运维经验,总结了一些tomcat的基础运维注意事项,希望对广大技术兄弟们有些帮助。

1      功能优化

1.1     硬件资源对tomcat的影响

     系统硬件性能直接影响tomcat的并发量,起决定作用的是CPUMEMCPU运行速度提升,会带来tomcat响应时间的缩短,mem大小决定工程需要内存的大小和工程的并发数量。

1.2     Java虚拟机调优

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

   JVM调优参见:http://vekergu.blog.51cto.com/9966832/1626733

1.2.1     JDK版本选择

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

1.2.2     JDK参数优化

Tomcat内存优化主要是对 tomcat 启动参数优化,我们可以在 tomcat 的启动脚本 catalina.sh 中设置 JAVA_OPTS参数。

1.   JAVA_OPTS参数说明

-server 启用jdk 的 server 版; 
-Xms   java虚拟机初始化时的最小内存; 
-Xmx  java虚拟机可使用的最大内存; 
-XX:PermSize    内存永久保留区域 
-XX:MaxPermSize   内存最大永久保留区域 
-Xms=-Xmx=服务器内存*70%,如部署tomcat,jboss在同一台服务器-Xms=-Xmx=服务器内存*80%*1/4,现公司服务器内存一般都可以加到最大4G,所以可以采取以下配置,把以下参数添加到catalina.sh里面,
 JAVA_OPTS=‘-Xms1024m -Xmx4096m -XX:PermSize=256M -XX:MaxNewSize=256m-XX:MaxPermSize=256m‘
 
#-Xmx6000m                        :设置JVM最大可用内存为6000MB
#-Xms6000m                        :设置JVM初始可用内存为6000MB
#-Xmn2g                              :设置年轻代大小为2G
#-Xss128k                             :设置每个线程的堆栈大小为128k
#-XX:NewRatio=4                 :设置年轻代与年老代的比值为4
#-XX:SurvivorRatio=4            :设置年轻代中Eden区与Survivor区的大小比值为4
#-XX:PermSize=512m                    :设置堆栈永久区起始大小为512m
#-XX:MaxPermSize=512m             :设置堆栈永久区最大大小为512m
#-XX:MaxTenuringThreshold=0     :设置垃圾最大年龄为0
#-XX:+UseParallelGC                     :选择垃圾收集器为并行收集器
#-XX:ParallelGCThreads=8             :配置并行收集器的线程数
#-XX:+UseParallelOldGC                :配置年老代垃圾收集方式为并行收集
#-XX:+UseAdaptiveSizePolicy     :并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低响应时>间或者收集频率等,此值建议使用并行收集器时,一直打开。


 

1.2.3     生产案例

    作者认为,生产环境对JVM的设置,还是需要根据java的运行状态,通过监控后,不断的调试的一个过程,没有那个配置一上来就可以适应所有的场景。以下就举列作者常用的一个JVM配置方式:

JAVA_OPTS="
-Xms1024m
-Xmx1024m
-Xmn384m
-XX:PermSize=64m
-XX:MaxPermSize=128m
-XX:+UseParallelOldGC
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc:/opt/tomcat/log/gc.log
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/tomcat/heap.bin"
说明:


1.   XmsXmx普遍选择配置相同的大小,实际大小根据实际情况调整,由小向大增加,没必要一开始就增加到很大的内存。

2.   XX:PermSize设置堆栈永久区起始大小,XX:MaxPermSize设置堆栈永久区最大大,其实设置比默认值大写即可,或者默认也可以。作者这个这两个值,是因为出现过永久区内存溢出,才进行设定的。

3.   UseParallelOldGCPrintGCDateStampsPrintGCDetailsXloggc:/opt/tomcat/log/gc.log设置GClog日志,这个对分析tomcatJVM内存使用情况非常有效。

4.   XX:+HeapDumpOnOutOfMemoryErrorXX:HeapDumpPath=/opt/tomcat/heap.bin"设置内存溢出时,输出HeapDump,具体如何使用分析HeapDump文件,请参考:http://vekergu.blog.51cto.com/9966832/1619640

5.   作者对JVM参数设置的做法,调整合适的JVM内存大小,开启GClogHeapDump即可。

1.3     tomcat集群之session共享

1.3.1     基于tomcat集群的session共享

 {TOMCST_HOME}/conf/server.xml取消下面代码注释即可:

<ClusterclassName="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>


1.3.2     基于memcached存储session共享

 具体配置方法见:http://vekergu.blog.51cto.com/9966832/1672833

1.4     站点的默认网页、自定义错误页面、禁止列目录等功能

这些功能开发会在工程的WEB-INF目录下的web.xml中设置,运维了解下就好

1.4.1     默认主页

   <welcome-file-list>
       <welcome-file>index.html</welcome-file>
       <welcome-file>index.htm</welcome-file>
       <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>

1.4.2     自定义错误页面

<error-page> 
<error-code>404</error-code> 
<location>/404.htm</location> 
</error-page>


1.4.3     定义会话超时时间

   <session-config>
       <session-timeout>30</session-timeout>
   </session-config>

1.4.4     禁止列目录

       <init-param>
           <param-name>listings</param-name>
           <param-value>false</param-value>
       </init-param>

1.5     管理AJP端口

    AJP是为 Tomcat HTTP 服务器之间通信而定制的协议,能提供较高的通信速度和效率。如果tomcat前端放的是apache的时候,会使用到AJP这个连接器。由于我们公司前端是由nginx做的反向代理,因此不使用此连接器,因此需要注销掉该连接器。在{TOMCST_HOME}/conf/server.xml中找到下列代码,注释即可

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

1.6     取消默认gc监听

    如果开启了GClog,再开启GC监听,会影响GClog输出,功能重复,可以选择取消。

 <!-- 内存泄露侦测,对于垃圾回收不能处理的对像,它就会做日志,开启gcc后,不需要这个功能-->
 <!-- ListenerclassName="org.apache.catalina.core.JreMemoryLeakPreventionListener"gcDaemonProtection="false"/ -->

2      性能优化

2.1     屏蔽DNS查询

    Web应用程序可以通过Web容器提供的getRemoteHost()方法获得访问Web应用客户的IP地址和名称,但是这样会消耗Web容器的资源,并且还需要通过IP地址和DNS服务器反查用户的名字。因此当系统上线时,可以将这个属性关闭,从而减少资源消耗,那么Web应用也就只能记录下IP地址。修改的属性是enableLoopups="false"

2.2     调整线程数

    Tomcat通过线程池来为用户访问提供响应,对于上线的系统初步估计用户并发数量后,再调整线程池容量。例如,用户并发数量在100左右时,可以设置minProcessors="100"maxProcessors="100"。将最大和最小设置为一样后,线程池不会再释放空闲的线程,当用户访问突然增加时,不需要再消耗系统资源去创建新的线程。

2.3     调整最大连接数

   这个其实最复杂,即使用户并发量大,但是系统反应速度快,也没必要把这个值设置太高,高了系统需要消耗大量的资源去切换线程,但是如果设置太低也会造成应用无法满足用户并发需要。因此设置这个最好能够结合整个系统的跟踪与调优,使系统达到最好的平稳状态,一般设置为maxProcessors1.5倍即可。

2.4     调整网络超时

    主要是HTTP协议也有个连接过程,客户端连接到服务器上后,如果长时间没有得到处理就会被释放。如果服务器处理速度较慢,但是希望每个用户都能得到有效处理,或者网络环境不好,需要保证用户不会因为超时中断,也可以把时间加长。但是一般设置成connectionTimeout="30000"即可。太长对系统来说价值不大,反而会浪费系统资源在无谓的长连接上。

2.5     压缩管理

    tomcat作为一个应用服务器,也是支持 gzip 压缩功能的。我们可以在 server.xml 配置文件中的 Connector 节点中配置如下参数,来实现对指定资源类型进行压缩。

 

  compression="on"            # 打开压缩功能
  compressionMinSize="50"     # 启用压缩的输出内容大小,默认为2KB
  noCompressionUserAgents="gozilla, traviata"      # 对于以下的浏览器,不启用压缩
  compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"# 哪些资源类型需要压缩

因为nginx代理,所以tomcat自身不需要进行压缩,会给服务器增加压力

2.6     tomcat的三种运行模式选择

2.6.1     Bio

默认的模式,性能非常低下,没有经过任何优化处理和支持。

2.6.2     Nio

利用java的异步io护理技术,no blocking IO技术.

 

想运行在该模式下,直接修改server.xml里的Connector节点,修改protocol

 

 <Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
         connectionTimeout="20000"
         URIEncoding="UTF-8"
         useBodyEncodingForURI="true"
         enableLookups="false"
         redirectPort="8443"/>

启动后,就可以生效。

2.6.3     Apr

安装起来最困难,但是从操作系统级别来解决异步的IO问题,大幅度的提高性能.。必须要安装aprnative,直接启动就支持apr

 

安装APR

sudo yum -y install apr  apr-devel
tar zxvf tomcat-native.tar.gz //该文件在tomcat的bin目录下面
cd tomcat-native-1.1.24-src/jni/native
./configure--with-apr=/usr/bin/apr-1-config
make
make install

 

安装完成之后 会出现如下提示信息

Libraries have been installed in:

/usr/local/apr/lib

 

安装成功后还需要对tomcat设置环境变量,方法是在catalina.sh文件中增加一 行:

CATALINA_OPTS="-Djava.library.path=/usr/local/apr/lib"
修改8080端对应的
protocol="org.apache.coyote.http11.Http11AprProtocol"

2.7     Tomcat连接相关参数总结

Tomcat 配置文件 server.xml 中的 <Connector ... /> 配置中

maxThreads 客户请求最大线程数
minSpareThreads    Tomcat初始化时创建的 socket 线程数
maxSpareThreads   Tomcat连接器的最大空闲 socket 线程数
enableLookups      若设为true, 则支持域名解析,可把 ip 地址解析为主机名
redirectPort        在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort端口
acceptAccount       监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads  )
connectionTimeout   连接超时
minProcessors         服务器创建时的最小处理线程数
maxProcessors        服务器同时最大处理线程数
URIEncoding    URL统一编码
compression 打开压缩功能  
compressionMinSize   启用压缩的输出内容大小,这里面默认为2KB
compressableMimeType 压缩类型
connectionTimeout 定义建立客户连接超时的时间. 如果为 -1, 表示不限制建立客户连接的时间


 

2.8     生产配置实例

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"   #nio  利用java的异步io护理技术,noblocking IO技术.
        URIEncoding="UTF-8"    #设置编码
        minSpareThreads="25"  #Tomcat初始化时创建的 socket线程数
        maxSpareThreads="75"  #Tomcat连接器的最大空闲socket 线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。默认值50
        enableLookups="false"  #屏蔽DNS查询
        disableUploadTimeout="true"  #该标志位表明当执行servlet时,是否允许servlet容器使用一个不同的、更长的连接超时。启用该标志位将导致在上传数据时,要么使用更长的时间完成上传,要么出现更长的超时。如果不指定,该属性为“false”。       
        connectionTimeout="20000"   #网络超时时间
        acceptCount="300"     #容许的最大连接数,一般设置为maxProcessors的1.5倍即可,满了之后客户请求会被拒绝(不能小于maxSpareThreads  )
        maxThreads="300"     #客户请求最大线程数,默认值为“200”
        maxProcessors="1000"   #最大连接线程数,即:并发处理的最大请求数,默认值为75 ,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程
        minProcessors="5"      #最小空闲连接线程数,用于提高系统处理性能,默认值为10
        useURIValidationHack="false"
        compression="on"   #打开压缩功能
        compressionMinSize="2048" #启用压缩的输出内容大小,这里面默认为2KB
        compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"   #压缩类型
        redirectPort="8443"/>

             

3      安全优化

3.1     tomcat影藏版本信息

Tomcat 安装目录下的lib目录下,名称为 catalina.jar,直接修改catalina.jar中的文件,org/apache/catalina/util/ServerInfo.properties

server.info=Apache Tomcat/7.0.53

3.2     禁用 Tomcat 管理页面

    我们线上是不使用 Tomcat 默认提供的管理页面的,因此都会在初始化的时候就把这些页面删掉。这些页面是存放在 Tomcat 安装目录下的webapps目录下的。我们只需要删除该目录下的所有文件即可。当然,还有涉及管理页面的2个配置文件host-manager.xml manager.xml 也需要一并删掉。这两个文件存放在 Tomcat 安装目录下的conf/Catalina/localhost目录下。

3.3     用普通用户启动 Tomcat

    为了进一步安全,我们不建议使用 root 来启动 Tomcat。这边建议使用专用用户 tomcat 或者 nobody 用户来启动 Tomcat。在启动之前,需要对我们的tomcat 安装目录下所有文件的属主和属组都设置为指定用户。

3.4     分离 Tomcat 和项目的用户

为了防止 Tomcat 被植入 web shell 程序后,可以修改项目文件。因此我们要将 Tomcat 和项目的属主做分离,这样子,即便被搞,他也无法创建和编辑项目文件。

3.5     关闭war自动部署

默认 Tomcat 是开启了对war包的热部署的。为了防止被植入木马等恶意程序,因此我们要关闭自动部署。

修改实例:

 
     <Host name="localhost" appBase=""
           unpackWARs="false" autoDeploy="false">

3.6     更改关闭 Tomcat 实例的指令

    server.xml中定义了可以直接关闭 Tomcat 实例的管理端口。我们通过 telnet 连接上该端口之后,输入 SHUTDOWN (此为默认关闭指令)即可关闭 Tomcat 实例(注意,此时虽然实例关闭了,但是进程还是存在的)。由于默认关闭Tomcat 的端口和指令都很简单。默认端口为8005,指令为SHUTDOWN 。因此我们需要将关闭指令修改复杂一点。

    当然,在新版的 Tomcat 中该端口仅监听在127.0.0.1上,因此大家也不必担心。除非黑客登陆到tomcat本机去执行关闭操作。

      修改实例:

<Server port="8005"shutdown="9SDfjsd29jf24sdff0LSDdfJKS9DKkjsd">

4      内核优化

   在修改内核参数的时候,建议大家逐个设置,然后反复试验,切勿图方便直接拿上就用,一次全部替换。

优化网络参数

修改/etc/sysctl.cnf文件,在最后追加如下内容:

net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 65536

 

保存退出,执行sysctl-p生效

内核参数详细作用,可以参考:http://blog.chinaunix.net/uid-21505614-id-2181210.html

 

5      tomcat监控

5.1     配置tomcatstatus状态页

步骤1:修改%tomcat安装路径%\conf \tomcat-users文件,配置admin设置权限。在<tomcat-users>中增加部分内容。具体如下:

 <role rolename="manager-gui"/>
 <user username="manager"password="1234" roles="manager-gui"/>

  注:用户名:manager,密码:1234

步骤2:完成后,启动tomcat,输入:http://localhost:8080  --(IP,端口号,可远程访问)

点击status,输入账号,密码(manager,1234),进入status,时时刷新页面,查看当前tomcat状态。 或者直接访问:http://localhost:8080/manager/status页面。

备注1:若希望整个服务器的性能数据以一个单行的xml文件形式表示,则进入如下界面:http://localhost:8080/manager/status?XML=true

备注2:若服务器中存在几个项目,单独对某个项目进行监控,则需要另行增加代码。

 

Free memory: 304.84 MB Total memory: 903.00MB Max memory: 7273.00 MB
Free memory:空闲内存大小。
Total memory:总内存大小。
Max memory:最大内存大小。
 
Max threads: 200 Current thread count: 10Current thread busy: 1 Keeped alive sockets count: 1Max processing time: 187 msProcessing time: 0.281 s Request count: 32 Error count: 3 Bytes received: 0.00MB Bytes sent: 0.12 MB
Max threads:最大线程数。
Current thread count:最近运行的线程数。
Max processing time:最大CPU时间。
Processing time:CPU消耗总时间
Request count:请求总数。
Error count:错误的请求数。
Bytes received:接收字节数。
Bytes sent:发送字节数。


 

访问地址:

curl --user manager:1234   http://you_tomcat_ip:port/manager/status?XML=true

 

5.2     tomcat监控脚本

 

#!/bin/bash
#auther:gushao
#time:2015-5-4
#========================DefaultSettings===============================
# address of status page
STATUS_ADDR="http://localhost:8080/manager/status?XML=true"
USER="manager"
PASS="1234"
# sample rate, default: 5seconds
SAMPLE_RATE=5
# if press "Ctrl+c", stop monitor
EXIT_SIGNAL=2
# connector to monitor
CONNECTOR="http-8080"
# result directory to store data
RESULT_DIR="/tmp"
# perf data file
PERF_DATA="perf_data"
# jvm data file
JVM_DATA="jvm_data"
# connector data file
CONNECTOR_DATA="connector_data"
# thread data file
THREAD_DATA="thread_data"
# request data file
REQUEST_DATA="request_data"
 
# ===========================Output ErrorMessage========================
# Show Error Message and exit, get oneparameter
errorMsg()
{
       if [[ $# -eq 1 ]]; then
                echo "Runtime Error:$1"
                exit 1
       else
               echo "Function Error:errorMsg"
                exit 127
       fi
}
 
# =========================Get DataFunction=============================
# Get performance data, no parameter wanted
getPerfData()
{
       cd $RESULT_DIR
       wget --http-user="$USER" --http-password="$PASS""$STATUS_ADDR" -O "$PERF_DATA" || errorMsg "Failed toget data, please check the connection"
       # JVM data
       sed ‘s/.*<jvm>//g;s/<\/jvm>.*//g‘ $PERF_DATA | awk -F \‘ ‘{print $2, $4, $6 }‘ >> $JVM_DATA
       # ‘Connector data
       sed ‘s/.*‘$CONNECTOR‘.>//g;s/<\/connector>.*//g‘ $PERF_DATA>> $CONNECTOR_DATA
       # Thread data
       sed ‘s/.*<threadInfo//g;s/\/>.*//g‘ $CONNECTOR_DATA | awk -F\" ‘{ print $2, $4, $6 }‘ >> $THREAD_DATA
       # " Request data
       sed ‘s/.*<requestInfo//g;s/\/>.*//g‘ $CONNECTOR_DATA | awk -F\" ‘{ print $2, $4, $6, $8, $10, $12 }‘ >> $REQUEST_DATA
 
}
 
# ========================Build ChartFunction==========================
# "according the data, build the chart(use gnuplot)
buildChart()
{   
       TITLE=""
       OUTPUT=""
       PLOT=""
       YRANGE="[0:]"
       case "$1" in
                "jvm" )
                TITLE="JVM"
               OUTPUT="jvm_graph.png"
                PLOT="plot ‘jvm_data‘using 1 title ‘free‘ w linespoints,                 ‘jvm_data‘ using 2 title‘total‘ w linespoints,                ‘jvm_data‘ using 3 title ‘max‘w linespoints"
                ;;
 
                "thread" )
                TITLE="Thread"
               OUTPUT="thread_graph.png"
                PLOT="plot ‘thread_data‘using 1 title ‘max threads‘ w linespoints,                ‘thread_data‘ using 2 title‘current thread count‘ w linespoints,                ‘thread_data‘ using 3 title‘current thread busy‘ w linespoints"
                ;;
 
                "request" )
                TITLE="Request"
                YRANGE="[-1:]"
               OUTPUT="request_graph.png"
                PLOT="plot ‘request_data‘using 1 title ‘max time‘ w linespoints,                ‘request_data‘ using 2 title‘processing time‘ w linespoints,                ‘request_data‘ using 3 title‘request count‘ w linespoints,                ‘request_data‘ using 4 title‘error count‘ w linespoints,                ‘request_data‘ using 5 title‘bytes received‘ w linespoints,                ‘request_data‘ using 6 title‘bytes sent‘ w linespoints"
                ;;
       esac
 
       # build graph
       gnuplot <<EOF
       set terminal png small size 480,360
       set title "$TITLE"
       set yrange $YRANGE
       set grid
       set xlabel "timeline (s)"
       set output "$OUTPUT"
       $PLOT
EOF
}
 
# ========================Build ReportFunction=========================
# include data and chart, give a readablehtml report
buildReport()
{
       # build graph jvm, request,thread
       buildChart "jvm" || errorMsg "Function Error: build jvmgraph"
       buildChart "thread" || errorMsg "Function Error: buildthread graph"
       buildChart "request" || errorMsg "Function Error: buildrequest graph"
       # build html report
}
 
# ========================Stop MonitorFunction
# call buildReport function
stopMonitor()
{
   echo "Monitor stopped, and we are building the report ..."
   buildReport || errorMsg "Function Error: buildReport"
   exit
}
 
# =============================MainFunction=============================
trap "stopMonitor" $EXIT_SIGNAL
#收到stopMonitor信号,则中断退出
while :
do
       getPerfData || errorMsg "Failed to get performance data"
       sleep $SAMPLE_RATE
done


本文出自 “运维路上” 博客,请务必保留此出处http://vekergu.blog.51cto.com/9966832/1672931

tomcat配置调优与安全总结

标签:tomcat 配置 调优 安全 监控

原文地址:http://vekergu.blog.51cto.com/9966832/1672931

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!