认知迭代:Tomcat性能提升的实战操作,提升60倍以上tomcat性能

经常听到不少人说一句话:tomcat性能差,不如去用weblogicwebspherejboss”,我想说,用什么东西得根据实际情况来吧,如果给一个小公司的外包开发一个普通的项目,给她用OracleWeblogic?在高速公路上,拖拉机是没奔驰快,但是到了乡下,奔驰可就不行喽。看完本文,您将对tomcat的使用有个新的认识。

 

.影响性能的几个重要指标 

在开始动手优化小猫的性能之前,我们务必要先了解几个概念。

1.1吞吐量

吞吐量是指在一次性能测试过程中网络上传输的数据量的总和。

对于交互式应用来说,吞吐量指标反映的是服务器承受的压力,在容量规划的测试中,吞吐量是一个重点关注的指标,因为它能够说明系统级别的负载能力。另外,在性能调优过程中,吞吐量指标也有重要的价值。

1.2吞吐率

单位时间内网络上传输的数据量,也可以指单位时间内处理客户请求数量。它是衡量网络性能的重要指标,通常情况下,吞吐率用字节数/来衡量,当然,你可以用请求数/页面数/来衡量。其实,不管是一个请求还是一个页面,它的本质都是在网络上传输的数据,那么来表示数据的单位就是字节数。

 1.3事物

用户某一步或几步操作的集合。不过,我们要保证它有一个完整意义。比如用户对某一个页面的一次请求,用户对某系统的一次登录,淘宝用户对商品的一次确认支付过程,这些我们都可以看作一个事务。那么如何衡量服务器对事务的处理能力,又引出一个概念——TPS

1.4 TPS

每秒钟系统能够处理事务或交易的数量。

1.5点击率

点击率可以看做是TPS的一种特定情况,点击率更能体现用户端对服务器的压力,TPS更能体现服务器对客户请求的处理能力。

每秒钟用户向web服务器提交的HTTP请求数,这个指标是web应用特有的一个指标;web应用是请求-响应模式,用户发一个申请,服务器就要处理一次,所以点击是web应用能够处理的交易的最小单位。如果把每次点击定义为一个交易,点击率和TPS就是一个概念。容易看出,点击率越大,对服务器的压力也越大,点击率只是一个性能参考指标,重要的是分析点击时产生的影响。

需要注意的是,这里的点击不是指鼠标的一次单击操作,因为一次单击操作中,客户端可能向服务器发现多个HTTP请求。

1.6平均响应时间

也称为系统响应时间,它一般指在指定数量的VU情况下,每笔交易从mouseclickIE的数据刷新与展示之间的间隔,比如说:250VU下每笔交易的响应时间不超过2秒。

.我们要优化tomcat的目标

对以上几个性能方面的重要概念有了大致的了解后,我们要清楚优化tomcat的目标,我认为大体可以概括为2个目标:

1)承受更大并发用户数

2)性能方面取得大幅改善(系统平均性能提升至少20倍,甚至60倍)

. 从多方面来优化tomcat的性能

Tomcat的优化分为两块: JVM的优化,容器自身参数的优化。

3.1 JVM的优化

   3.1.1 32位操作系统和64位中JVM的比较

32位系统下JVM对内存的限制:不能突破2GB内存,即使在Win2003 Advanced Server下你的机器装有8GB-16GB的内存,而你的JAVA,只能用到2GB的内存,而在64位操作系统上无论是系统内存还是JVM都没有受到2GB这样的限制。

   3.1.2 tomcat启动行参数的优化

Tomcat首先跑在JVM之上的,因为它的启动其实也只是一个java命令行,首先我们需要对这个JAVA的启动命令行进行调优,本文是基于jdk 1.6环境。

Tomcat 的启动参数位于tomcat的安装目录\bin目录下,如果你是Linux操作系统就是catalina.sh文件,如果你是Windows操作系统那么你需要改动的就是catalina.bat文件。本文以linux环境为例来讲解,打开该文件,一般该文件头部是一堆的由##包裹着的注释文字,找到注释文字的最后一段。

 

敲入一个回车,加入如下的参数

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 "

参数解释:

-server

只要tomcat是运行在生产环境中的,这个参数必须加上。

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

 -Xms–Xmx

 JVM内存设置了,把XmsXmx两个值设成一样是最优的做法,有人说Xms为最小值,Xmx为最大值不是挺好的,这样设置还比较人性化,科学化。事实是如此吗?

大家想一下这样的场景:

一个系统随着并发数越来越高,它的内存使用情况逐步上升,上升到最高点不能上升了,开始回落,你们不要认为这个回落就是好事情,由其是大起大落,在内存回落时它付出的代价是CPU高速开始运转进行垃圾回收,此时严重的甚至会造成你的系统出现卡壳就是你在好好的操作,突然网页像死在那边一样几秒甚至十几秒时间,因为JVM正在进行垃圾回收。

因此一开始我们就把这两个设成一样,使得Tomcat在启动时就为最大化参数充分利用系统的效率,这个道理和jdbc pool里的minpool sizemaxpool size的需要设成一个数量是一样的原理。

如何知道我的JVM能够使用最大值啊呢?

在设这个最大内存即Xmx值时请先打开一个命令行,键入如下的命令:

 

如果是在32位系统下,我们试试2G内存行不行:

 

试试1700m

 

1700m都不可以,更不要说2048m了,2048m只是一个理论数值。这个跟机器也有关,有的能到1700m

 –Xmn

 设置年轻代大小为512m。整个堆大小=年轻代大小+年老代大小+ 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8

-Xss

是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程大约需要占用多少内存,可能会有多少线程同时运行等。一般不易设置超过1M,要不然容易出现out ofmemory

-XX:+AggressiveOpts

 启用这个参数,则每当JDK版本升级时,你的JVM都会使用最新加入的优化技术(如果有的话)。

-XX:+UseBiasedLocking

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

-XX:PermSize=128M-XX:MaxPermSize=256M

JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64

在数据量的很大的文件导出时,一定要把这两个值设置上,否则会出现内存溢出的错误。

XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4

那么,如果是物理内存4GB,那么64分之一就是64MB,这就是PermSize默认值,也就是永生代内存初始大小;

四分之一是1024MB,这就是MaxPermSize默认大小。

-XX:+DisableExplicitGC

在程序代码中不允许有显示的调用”System.gc()”。看到过有两个极品工程中每次在DAO操作结束时手动调用System.gc()一下,觉得这样做好像能够解决它们的out ofmemory问题一样,付出的代价就是系统响应时间严重降低。

 -XX:+UseParNewGC

对年轻代采用多线程并行回收,这样收得快。

-XX:+UseConcMarkSweepGC

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

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

 -XX:MaxTenuringThreshold

设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。

这个值的设置是根据本地的jprofiler监控后得到的一个理想的值,不能一概而论原搬照抄。

-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启动收集

-XX:CMSInitiatingOccupancyFraction=70

CMSInitiatingOccupancyFraction,这个参数设置有很大技巧,基本上满足(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn就不会出现promotion failed。在我的应用中Xmx6000Xmn512,那么Xmx-Xmn5488兆,也就是年老代有5488兆,CMSInitiatingOccupancyFraction=90说明年老代到90%满的时候开始执行对年老代的并发垃圾回收(CMS),这时还10%的空间是5488*10%=548兆,所以即使Xmn(也就是年轻代共512兆)里所有对象都搬到年老代里,548兆的空间也足够了,所以只要满足上面的公式,就不会出现垃圾回收时的promotion failed

因此这个参数的设置必须与Xmn关联在一起。

-Djava.awt.headless=true

这个参数一般我们都是放在最后使用的,这全参数的作用是这样的,有时我们会在我们的J2EE工程中使用一些图表工具如:jfreechart,用于在web网页输出GIF/JPG等流,在winodws环境下,一般我们的appserver在输出图形时不会碰到什么问题,但是在linux/unix环境下经常会碰到一个exception导致你在winodws开发环境下图片显示的好好可是在linux/unix下却显示不出来,因此加上这个参数以免避这样的情况出现。

上述这样的配置,基本上可以达到:

1.系统响应增快

2. JVM回收速度增快同时又不影响系统的响应率

3. JVM内存最大化利用

4. 线程阻塞情况最小化

3.2 Tomcat容器内的优化

前面我们对Tomcat启动时的命令进行了优化,增加了系统的JVM可使用数、垃圾回收效率与线程阻塞情况、增加了系统响应效率等还有一个很重要的指标,我们没有去做优化,就是吞吐量。

打开tomcat安装目录\conf\server.xml文件,定位到这一行:

 

这一行就是我们的tomcat容器性能参数设置的地方,它一般都会有一个默认值,这些默认值是远远不够我们的使用的,我们来看经过更改后的这一段的配置:

 

又是一大坨。。。

解释一下:

URIEncoding=UTF-8

使得tomcat可以解析含有中文名的文件的url,真方便,不像apache里还有搞个mod_encoding,还要手工编译。

maxSpareThreads

maxSpareThreads 的意思就是如果空闲状态的线程数多于设置的数目,则将这些线程中止,减少这个池中的线程总数。

minSpareThreads

最小备用线程数,tomcat启动时的初始化的线程数。

enableLookups

这个功效和Apache中的HostnameLookups一样,设为关闭。

connectionTimeout

connectionTimeout为网络连接超时时间毫秒数。

maxThreads

maxThreads Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数,即最大并发数。

acceptCount

acceptCount是当线程数达到maxThreads后,后续请求会被放入一个等待队列,这个acceptCount是这个队列的大小,如果这个队列也满了,就直接refuse connection

maxProcessorsminProcessors

Java中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同的地址空间。多线程帮助程序员写出CPU大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。

通常Windows1000个左右,Linux2000个左右。

useURIValidationHack

对于这个参数,我们要看一下tomcat的一段源码再说。

 security

       if (connector.getUseURIValidationHack()) {

           Stringuri = validate(request.getRequestURI());

           if(uri == null) {

               res.setStatus(400);

               res.setMessage("Invalid URI");

               throw new IOException("InvalidURI");

           } else {

               req.requestURI().setString(uri);

               // Redoing the URI decoding

               req.decodedURI().duplicate(req.requestURI());

               req.getURLDecoder().convert(req.decodedURI(),true);

           }

       }

可以看到如果把useURIValidationHack设成"false"可以减少它对一些url的不必要的检查从而减省开销。

enableLookups="false"

为了消除DNS查询对性能的影响我们可以关闭DNS查询

disableUploadTimeout

类似于Apache中的keeyalive一样

compression="on"compressionMinSize="2048"             

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

Tomcat配置gzip压缩(HTTP压缩)功能。

HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML,CSS,Javascript , Text,它可以节省40%左右的流量。更为重要的是,它可以对动态生成的,包括CGIPHP , JSP , ASP ,Servlet,SHTML等输出的网页也能进行压缩,压缩效率惊人。

1)compression="on" 打开压缩功能

2)compressionMinSize="2048" 启用压缩的输出内容大小,这里面默认为2KB

3)noCompressionUserAgents="gozilla,traviata" 对于以下的浏览器,不启用压缩

4)compressableMimeType="text/html,text/xml" 压缩类型

最后不要忘了把8443端口的地方也加上同样的配置,如果我们走https协议的话,我们将会用到8443端口这个段的配置,参数跟以上一样,这里就不再写出来了。

好了,我们的tomcat优化到这里就完成了,相信这样做下来,优化过的tomcat要比未经过优化的,性能提高20~60倍,有兴趣的童鞋可以照着做一下,顺便用LR或者ab测一下效果。

小猫飞起来了吗

为了简便,这里用轻量级测试工具Jmeter模拟150000个线程请求,试一下。

优化之前

 

优化之后

 

真变成飞猫了!

在生产环境可以结合apache也做次优化,如果再使用了负载均衡,那么系统的整体性能就更高了。

之前使用tomcat方面是不是弱爆了?

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值