java面试题

Liunx下Tomcat调优指南

1      概述

由于Tomcat的运行依赖于JVM,从虚拟机的角度我们把Tomcat的调整分为外部环境调优和自身调优两类来描述。

2      调优方案

1.1  外部环境调优

1)          操作系统性能优化

对于操作系统优化来说,是尽可能的增大可使用的内存容量、提高CPU的频率,保证文件系统的读写速率等。经过压力测试验证,在并发连接很多的情况下,CPU的处理能力越强,系统运行速度越快。对于并发数很大的情况来说,带宽也是影响系统性能的一个重要指标,因此要实现系统的快速响应,必须拥有较高的带宽。

建议使用64位操作系统,如果是32位操作系统,建议使用企业版。

2)          JAVA虚拟机性能优化

Tomcat需要依赖Java虚拟机运行。根据客户选用的主机的操作系统选择对应的 JDK的版本。无论哪个厂商的JDK,都建议使用最新的版本。

虚拟机可通过命令行的方式改变虚拟机使用内存的大小。如下表所示有两个参数用来设置虚拟机使用内存的大小。

Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。

Windows下,在文件% TOMCAT_HOME %/bin/catalina.bat,Unix下,在文件 $TOMCAT_HOME/bin/catalina.sh的前面,增加如下设置:

JAVA_OPTS=’-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】

需要把这个两个参数值调大。例如:JAVA_OPTS='-Xms256m -Xmx512m',表示初始化内存为256MB,可以使用的最大内存为512MB。

另外需要考虑的是Java提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关,应该通过分析实际的垃圾收集的时间和频率来调整。

如果堆的空间很大,那么完全垃圾收集(FULL GC)就会很慢,但是频度会降低。如果在客户系统中把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。对于SUN和HP等虚拟机,推荐将最小堆大小和最大堆大小设置为同一值,因为这样可以避免浪费用于时常调整堆大小所需的资源。

具体JVM 参数配置见附录一

3)          Tomcat与其它web服务器整合使用

虽然tomcat也可以作web服务器,但其处理静态html的速度比不上apache,且其作为web服务器的功能远不如apache,因此我们想把 apachetomcat集成起来,将htmljsp的功能部分进行明确分工,让tomcat只处理jsp部分,其它的由apache,IIS等这些 web服务器处理,由此大大提高Tomcat的运行效率

1.2  Tomcat自身调优

1)     禁用DNS查询

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

除非客户需要连接到站点的每个HTTP客户端的机器名,否则我们建议在生产环境上关闭DNS查询功能。可以通过Tomcat以外的方式来获取机器名。这样不仅节省了网络带宽、查询时间和内存,而且更小的流量会使日志数据也会变得更少,显而易见也节省了硬盘空间。对流量较小的站点来说禁用DNS查询可能没有大流量站点的效果明显。

2)     调整线程数

通过应用程序的连接器(Connector)进行性能控制的的参数是创建的处理请求的线程数。Tomcat使用线程池加速响应速度来处理请求。在Java中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同的地址空间。多线程帮助程序员写出CPU最大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。
    Tomcat中可以通过修改minProcessors和maxProcessors的值来控制线程数。这些值在安装后就已经设定为默认值并且是足够使用的,但是随着站点的扩容而改大这些值。minProcessors服务器启动时创建的处理请求的线程数应该足够处理一个小量的负载。也就是说,如果一天内每秒仅发生5次单击事件,并且每个请求任务处理需要1秒钟,那么预先设置线程数为5就足够了。但在你的站点访问量较大时就需要设置更大的线程数,指定为参数maxProcessors的值。maxProcessors的值也是有上限的,应防止流量不可控制(或者恶意的服务攻击),从而导致超出了虚拟机使用内存的大小。如果要加大并发连接数,应同时加大这两个参数。web server允许的最大连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右。

最好的方式是多设置几次并且进行测试,观察响应时间和内存使用情况。在不同的机器、操作系统或虚拟机组合的情况下可能会不同,而且并不是所有的web站点的流量都是一样的,因此没有一刀切的方案来确定线程数的值。

3)     负载均衡

对于并发要求很高的系统,我们需要采取负载均衡的方式来分担Tomcat服务器的压力。负载均衡实现大概有四种:

第一是通过DNS,但只能简单的实现轮流分配,不能处理故障;

第二是基于MS IIS,windows 2003 server本身就带了负载均衡服务;

第三是硬件方式,通过交换机功能或专门的负载均衡设备来实现;

第四种是软件的方式,通过一台负载均衡服务器进行,上面安装软件。使用Apache Http Server做负载均衡器,Tomcat集群节点使用Tomcat就可以做到上述第四种方式,这种方式比较灵活,成本相对比较低,另外一个很大的优点就是可以根据应用情况和服务器的情况做一些灵活的配置。所以一般推荐使用Apache+Tomcat集群来实现负载均衡。

4)     其他

Tomcat提供了防止恶意攻击或禁止某些机器访问的设置。

 Tomcat提供了两个参数供你配置:RemoteHostValve 和RemoteAddrValve。通过配置这两个参数,可以让你过滤来自请求的主机或IP地址,并允许或拒绝哪些主机/IP。与之类似的,在Apache的httpd文件里有对每个目录的允许/拒绝指定。

例如你可以把Admin Web application设置成只允许本地访问,设置如下:

 

如果没有给出允许主机的指定,那么与拒绝主机匹配的主机就会被拒绝,除此之外的都是允许的。与之类似,如果没有给出拒绝主机的指定,那么与允许主机匹配的主机就会被允许,除此之外的都是拒绝的。

1.3   APR库使用

Tomcat中使用APR库,其实就是在Tomcat中使用JNI的方式来读取文件以及进行网络传输。可以大大提升Tomcat对静态文件的处理性能,同时如果使用了HTTPS方式传输的话,也可以提升SSL的处理性能。

一般在Windows下,可以直接下载编译好的二进制版本的dll库文件来使Tomcat启用APR,一般建议拷贝库文件tcnative-1.dll到Tomcat的bin目录下。而在Linux下,可以直接解压和安装bin目录下的tomcat_native.tar.gz文件,编译之前要确保apr库已经安装。

怎么才能判断Tomcat是否已经启用了APR库呢?方法是通过看Tomcat的启动日志:

如果没有启用APR,则启动日志一般有这么一条:

org.apache.coyote.http11.Http11Protocolstart

如果启用了APR,则这条日志就会变成:

org.apache.coyote.http11.Http11AprProtocolstart

tcnative-1.dll 下载地址:http://tomcat.heanet.ie/native/

3      实际案例 – 全国综合办公平台

1.   运行环境

Ø  操作系统 :  Redhat Enterprise 5.8  32位

Ø  CPU配置:   Intel(R) Xeon(R) CPUE5-2407 0 @ 2.20GHz 双核

Ø  内存大小: 8G

Ø  Tomcat 版本 :  apache-tomcat-6.0.18

Ø  JDK 版本 :  1.6.0_30

2.   问题描述及分析

全国综合办公平台新UI上线初期,曾经出现了Tomcat服务频繁宕机的问题。通过查看日志发现主要导致宕机的原因为内存溢出和内存回收出错。

考虑到已做了硬件负载均衡以及服务器硬件配置,排除外部硬件因素,初步判定为代码内存泄漏或Tomcat自身问题。通过代码排查及优化后效果不明显,最终通过优化Tomcat配置解决宕机问题。

3.   解决措施

优化Tomcat JVM配置,修改catalina.sh 文件

l  调大内存:

-Xms2048m -Xmx2048m

l  增加参数:

-XX:-UseGCOverheadLimit-XX:+UseConcMarkSweepGC

4.   经验总结

之前做过Tomcat 的内存优化,但错误的认为JVM可以运行的最大内存不能超过1G,没有充分利用系统内存资源。

32位操作系统中,JVM可用内存最大不超过2G,而64位操作系统则无限制。实际工作可以使用 java -XmxXXXXM -version 命令来进行测试,然后逐渐的增大XXXX的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息。

附录:

一、    Tomcat JVM 常用参数说明

参数名

说明

  -server

tomcat默认是以一种叫java –client的模式来运行的,server即意味着你的tomcat是以真实的production的模式在运行的,这也就意味着你的tomcatserver模式运行时将拥有:更大、更高的并发处理能力,更快更强捷的JVM垃圾回收机制,可以获得更多的负载与吞吐量

-Xms / –Xmx

JVM Heap(堆内存)初始值/ 允许的最大值

建议,XmsXmx两个值设成一样,最大值设置为可用内存的最大值的80%

-XX:PermSize

-XX:MaxPermSize

java永久生成对象(Permanate generation)如,class对象、方法对象这些可反射(reflective)对象分配内存初始值及最大值

-XX:newSize

-XX:MaxNewSize

新生成对象能占用内存的初始值及允许的最大值

 -XX:+DisableExplicitGC

不允许有显示的调用”System.gc()

-XX:UseGCOverheadLimit

在抛出OOM之前限制jvm耗费在GC上的时间比例

UseConcMarkSweepGC

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

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

 

 


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页