websphere性能调整(0分)

小猪

Unregistered / Unconfirmed
GUEST, unregistred user!
本文是我在三个月前写成的,现在看来似乎可能有些落后了,而且,当时最初
写的目的先将东西写出来,然后再重新整理后那去投稿的,但后来事情很多,
也没有时间来整理了,因此这个稿子写的有些乱,而且用词造句也比较随意,
而且可能还有个别错误的地方也没有办法来一一修正了,再拿去投稿是不可能
了,因此在这里free出来,希望给大家能有些帮助。
---------------------------------------------------------------------------
从2001下半年开始一直到现在,我一直在做基于WebSphere的web应用,从3.5一直到5.0,其间颇多心得,因此把一些东西写出来跟大家分享。基本上来说,下面提到的一些东西主要还是针对一些中量级的应用的,对于重量级的应用,恐怕还得要具体问题具体分析的。
3.5版本从WebSphere的产品线来说,是比较特殊的,从4.0开始,WebSphere的整个架构就有了比较大的改变,才算是勉强按照j2ee规范在走了。因此我也就主要谈谈4.0和5.0这两个版本,如果哪位朋友不幸要跟3.5打交道,可以发邮件给我,我当不会藏私。不过,因为我的机器实在太烂(这就是辞职的坏处啊,在单位上的时候,有多少机器放在那儿让俺折腾啊),有些基于5.0的测试没法做,因此,主要还是针对4.0版本的,当然,在5.0中,其实很多东西并没有变化,只是在有些细节上我无法证实而已。
其实开始接触was的性能调整也是因为极为特殊的原因,当时刚刚开始写基于web的应用,写出来的东西自然性能不佳,再加上运气不好,正好碰到was的一个严重的问题使得系统的性能问题雪上加霜,因此迫不得已开始研究was的性能调优。
在开始之前,我先请大家关注一下自己手上的was的版本号,was的主要版本号有三位,其中,最关键的是第三位,这是补丁的编号,我在使用was的过程中,有一项例行工作就是定期到ibm网站上检查补丁发布情况,其中最让我挠头的就是该死的4.0版本了,一直打到pack5以后,我才结束了与ibm技术支持人员的持久战。其间,颇多怪异的bug层出不穷,也许,我的运气也太好了一些,因为曹晓刚同学似乎很少碰到我遇到的问题,而经常我发现ibm网站上的bug说明中列举的可能性最大的bug发作环境通常跟我的环境非常一致。
需要说明的是,我这里提到的httpserver虽然可以泛推到was支持的各种httpserver上,但我的所有测试和调整都是基于随was一起提供的ibm http server。
首先,我来讲讲was性能相关的一个重要概念:传输队列。事实上,ibm的文档资料上提到的传输队列仅指在http server和application server之间转发请求的一个队列,不过,这里,我将这个概念泛化一下,将传输队列的概念扩展到从客户端浏览器开始,一直到数据库链接结束的一个传输链。它应该是这个样子:
客户端浏览器-》HTTP SERVER-》APPSERVER-》DATABASE
在这个请求链中,第一个可能需要排队等待的就是客户端浏览器和http server之间,如果http server过于繁忙,即使后面的appserver非常空闲,那么,客户端浏览器也必须等待。同样的,http server和appserver之间也存在同样的问题,即使database非常空闲,如果appserver此时繁忙的话,从http server转发过来的请求也必须等待,而此时,可能某个等待的请求是要调用一个数据库的费时的存储过程,但是很不幸,它没法把这个请求发送到空闲的数据库上去,因为负责处理这个请求的appserver此时非常繁忙。因此,这里有一个基本的思想就是:合理的分配各个节点的负载,永远不要使位于队列后面的节点比前面的节点轻松。
还有一个需要注意的,还是上一段提到的最后那个httpserver和appserver之间的传输,如果我加大appserver允许的请求数,会有什么后果,的确,从httpserver传过来的请求无须再等待了,全部都交给appserver去处理了,这样以来,httpserver的负担也就下降了,因为请求转发给appserver后,它也可以腾出手来接受更多的客户端请求了,想想会有什么后果?appserver不可能无限制的接收httpserver的请求,一来,我们加大appserver的处理请求数,已经加大了系统的负担,二来,不论如何加大appserver的负载能力,总是有限的,于是,剩下的无法处理的请求会形成一个队列,这就是httpserver和appserver之间的传输队列,越来越多的请求堆积在这个队列中,也会严重的消耗系统资源。
从3.5到4.0和5.0,在这里的调整是不一样的,3.5调整的是每个节点间的队列的大小,即定义有多少应该等待,而从4.0开始,定义的是每个节点的处理能力,即每个节点可以同时处理多少个请求。
调整的基本原则很简单,要使得所有的请求在这个传送队列中排队的情况呈一个漏斗型:也就是说,越是前面的节点,越要处理更多的请求,这样,必然会有一部分请求在队列中等待,但是,这个队列不能太大,因此位于后面的节点的处理能力应该是略小于前一个节点,这个比例通常是70%-80%,ibm文档上提到的这个比例比我给出的要小一点,但根据我的经验来看,对于一个中量级的应用,70%-80%的比例应该是比较合理的。
一般来说,在通常情况下,一个客户端请求虽然可能会导致多次访问数据库,但通常不需要多个数据库连接来支持,除非使用了多线程访问。在最一般的情况下,一个客户端请求会导致一个数据库连接,那么,如果打算支持100个并发的请求,那么,httpserver的连接数应该设为100,同样,appserver的连接数-在4.0以后的版本中用web线程数来表示,就应该是70左右,接下来,datasource的数字就应该是50左右了。
不过,如果按照上面的方法来调整的话,你肯定得不到一个满意的效果,事实上,按照这种理论来进行调整的情况,是需要你的系统负载已经接近硬件极限的情况下进行的。显然,上面举出的负载,大多数运行was的服务器都是可以轻松应付的,在这种情况下,按照上面提到的规则进行调整,未免太浪费硬件了,在httpserver和appserver在一台机器上,database在另一台机器的情况下(我相信这是一个比较典型的配置),我一般这么做:假设需要的并发是100,那么,在solaris上-httpserver的连接数是150,appserver的web线程数是120;在windows2000上-httpserver的连接数是300,appserver的web线程数是250;至于数据库连接,我的意见是-在硬件资源足够的情况下,能设多大就设多大吧,反正,不要让数据库连接成为系统的瓶颈。先看看solaris的配置,显然,我为100的并发需求留了一点扩展的余地,而且这个余地还不算小。再来看看2000下的配置,也许大家会很吃惊,为什么我会留出这么大的余量。事实上,was从3.5到4.0,在2000上它的转发队列的处理都存在极为严重的问题,在5.0中,应该说,这个问题得到了一定程度的解决,显得不是那么严重了,但仍然是一个值得关注的问题。
简单的说,情况是这样的,比如客户端发出了一个请求,然后httpserver将这个请求转发给appserver等待appserver的返回,此时,客户端可能发生一些事情:客户端浏览器可能被关闭;或者客户端浏览器发出了一个新的请求;甚至于我还怀疑引发问题的原因可能是因为我不同的帧在同时刷新的缘故(前面两个是得到我的测试的证明的,后面一个是我一直强烈怀疑的,却从未证实)。来看看被我证实的情况,如果客户端浏览器关闭或者发出了新的请求,事实上,前面一个请求都已经被客户端放弃了,但是,httpserver(这里的httpserver特指ibm http server,因为我没有对其他was支持的httpserver做过相关测试)并不知道,一方面,它还在傻傻的等待appserver的返回,appserver当然更不知道这个请求已经被放弃了,于是appserver兢兢业业的处理完这个请求,然后老老实实的把结果返回给httpserver(其实一直到这一步,was5.0都还没有什么变化,只是后面有所改进),有趣的事情发生了,傻的该死的httpserver会一直努力的、锲而不舍的、永不放弃的往已经被客户端放弃的连接中试图回写应答,看到这里,相信大家已经快要晕倒了,不过还有更让人恼火的事情,就是我曾经把那台宕掉的机器放在那里休息了一晚上,httpserver仍然没有放弃它可笑的努力。这种情况的直接后果就是httpsrever允许的连接数被占用,于是拒绝正常的客户端请求,而且,httpserver和appserver之间的转发队列也可能被严重堵塞,因此,我发现单纯的重起httpserver是没用的,一定要同时重起appserver。Was5.0在这个问题上有所改进,httpserver在试图回写客户端的时候会发现异常,然后放弃掉这个连接,然而,由于在回写失败之前was并不知道客户端已经放弃,因此,这些无效的请求仍然占用了大量的appserver的资源。由于这个原因,was仍然可能宕机,但这一点我现在已经无法进行工程级的测试了,只能说是我的推测。
在正常的访问情况下,不会有人不断的放弃连接和请求,因此这个现象是慢慢累积起来的(但是累积的速度仍然使我有理由怀疑,可能还有其他更一般的原因导致了这个结果),给出较大的余量,一般来说是可以解决问题的,而且,如果是was5的话,因为httpserver最终还是能够放弃连接释放资源的,因此,在was5下,这个余量可以适当的放小一点。不过,如果是在2000下使用was的话,我仍然强烈建议在较大并发量的情况下,要密切关注系统的运行情况,密切监控几个节点的负载。
非常幸运的是,在unix系统上,似乎was并没有这样的问题,我们曾经设计的测试,在2000上可以轻易的让was宕机,在solaris上was却纹丝不动,而且,监控httpserver的连接变动情况表明,httpserver非常聪明。
对于数据库连接的处理,前面我提到,在应用负载没有达到硬件极限的情况下,最好能够尽量的放大这个值,也就是不要让数据库连接成为系统的瓶颈,当然,这时也要考虑数据库服务器的负载能力,这个连接数不要让数据库吃不消。有一个需要注意的是,在稳定的生产环境下,最好将最小值和最大值设为一样,这将省去was在负载波动时不停的释放和建立连接的无谓消耗。
值得提到的一点是,在创建了多个应用服务器进程的情况下,如果分布在这多个应用服务器进程中的应用引用到了同一个数据源的的话,那么每一个引用进程都会创建一个相同大小的连接池,而不是多个应用进程共用一个连接池,因此需要注意不要超过了数据库的连接限制和过多的耗费应用服务器节点的硬件资源。
关于连接的问题就到这里,接下来是关于java虚拟机的调整。首先,要提到关于hotspot的问题,关于hotspot,大家可以到sun的网站上去看详细的介绍,下面是我从别处copy过来的一段简单的介绍:
使用HotSpot
HotSpot JVM作为java 2 SDK 的一个附加模块,使用了state-of-the-art 技术大大的提高了系统性能:
1. 适应编译:HotSpot JVM会在程序的运行过程中分析性能的瓶颈("hot spots"),然后编译这些和性能提高最紧密的部分。
2. 改善的Garbage collection
3. 线程同步优化
??HotSpot JVM使用两个机器字(two-machine-word) 作为对象的header,而不象大多数JVM使用三个机器字,这样大约可以节省10%的堆内存空间,加速了对所有对象的扫描。
HotSpot JVM 也丢弃了 handle 的概念,对象引用的实现是通过直接指针,减少了内存的使用和提高了处理速度。访问实例变量象C 语言一样的高效。
可以去http://java.sun.com/products/hotspot/2.0/download.html 下载Java HotSpotTM Server VM 2.0,执行安装即可。如果需要可以针对 jdk 和 jre分别进行安装。
HotSpot JVM 分为 client 和 server 版本,分别针对典型的客户端应用程序和服务器端应用进行了优化。Jdk1.3安装后就包含了 Java HotSpot Client VM,上面安装的是Java HotSpot Server VM。
可以通过命令行参数选择要使用的JVM:
· java -server :Java HotSpot Server VM
· java -hotspot : Java HotSpot Client VM
· java -classic : Java 2 Classic VM
缺省情况是使用 HotSpot Client VM。可以用 java -server -version 来查看版本信息,确定是否以正确安装。
只要针对不同的应用,选择Client 或Server HotSpot VM。对于Server-side应用,有时性能会提高20%,只要简单的在命令行启动Server 时加上 -server 。
从上面可以看出,使用hotspot是可以提高性能的,一般来说,我们安装的jvm只安装了hotspot client,不过,websphere在运行过程中是使用自带的jre,而这个jre已经安装了hotspot server。要确认这一点非常容易,进入websphere安装目录下的jre所在目录,执行“java -version”,可以看到列出的版本号,最下面一行会列出hotspot的版本,在此处列出的hotspot也是jvm在运行时缺省采用的hotspot版本(主要就是client和server的区别)。大家都知道websphere在运行时会有一个adminserver的进程,这个进程是was的管理进程,而发布在was上的应用通常会是另外一个单独的java进程,在was中这个进程被称为一个应用程序服务器。
Was4中,创建的应用程序服务器进程会被自动加上-server的参数,因此,我们不必自己在jvm参数中加上这一项。值得一提的是,我手上有两个was5的版本,一个是application server,一个是application server enterprise edtion,但它们自带的jvm居然都是CLASSIC JVM,我不知道是因为我拿到的不是ibm的正式产品的原因,还是ibm有某种特殊的考虑,我想如果使用was5的话,这需要特别注意一下,至于注意以后应该怎么办,呵,我也还没想好,或者试试自己安装hotspot,或者看看ibm的补丁会不会解决这个问题?先不管这个,这里我要讨论的是jvm的内存参数,通常我们运行was的服务器内存都不会小,我们也知道,java中的对象,都是在堆上创建的,但是很遗憾的是,jvm在启动时如果不为它指定一个内存参数的话,那么缺省的初始堆大小是2M,最大堆大小只有64M,显然,这也太浪费我们那庞大的内存了。初始堆大小的参数是-Xmsn,最大堆大小的参数是-Xmxn,最后那个n就是设置的数值大小,必须是1024的整数倍。不过was做的非常不错,在管理控制台中有图形界面可以配置这个参数。按照我一般的经验,如果那台机器只专门用来跑特定应用的话,那么为这个应用建立的应用程序服务器配置的jvm参数中,初始堆大小和最大堆大小通常会配置为物理内存的一半。这里之所以把初始堆大小和最大堆大小配成一样,其实和前面提到的datasource的配置是一样的道理,避免在负载波动时重新分配内存的消耗。当然,这个参数还是需要根据实际的情况来决定,比如可能同一台机器上还有其他程序在运行,那么这个值应该小一点,可能你的一个应用程序服务器中发布了几个应用,那么这个值应该大一点,或者你建立了多个应用程序服务器,那么需要在几个java进程间合理分配内存的占用情况。其实对于jvm的内存分配,还可以进一步的有多个细化的参数可以配置,但我觉得在一般的情况下似乎没有必要,总的来说,有句话还是说的好:优化程序比优化环境要有效的多。如果需要,可以到http://java.sun.com上去看详细的jvm设置的文档。值得一提的是,was在安装后一般会创建一个缺省的应用程序服务器,我不大赞成把自己的应用发布到这个缺省服务器上。因为缺省服务器发布了一个sample应用,可以帮助我们确定是否正确安装以及在运行中出现问题时确定was的状况用,所以我一般不会删掉它,只是将其置为停止状态,然后创建自己的应用程序服务器。
上面给出的几个调整,基本上来说,针对一个轻量级或者中量级的应用是非常有效的,而was中还有诸多的缓存之类的设置,我的感觉是,针对一个负载不大的应用,缺省值基本上是足够的,当然,也可以针对特定问题调整某个特定缓存的大小,不过这已经不是本文打算讨论的了,事实上,针对每一个具体版本的websphere,ibm都有相应的性能调整手册发布,要想获得最优化的性能,仔细阅读ibm的性能调整手册是必不可少的,而本文提到的几点,只是我在工作实践中认为在大多数情况下最为重要和最为简单有效的手段,因此特别写出来与大家共享,也可以作为大家在阅读ibm相关文档时的一个纲要。如果面对一个重量级的应用,我想我文中提到的内容也能够对大家有所帮助,只是对于一个重量级的应用,恐怕更需要具体情况具体分析,针对特定的瓶颈作特别的设定和调整了。
附记:在was4.0中,was开始提供一个性能调整的向导界面,其实从这个向导中可以看出,基本上配置的就是我在文中提到的一些事项,当然,我这里没有涉及到ejb的相关设置,一来,我觉得一个轻量级或者中量级的应用一般不会用到ejb,二来,涉及到ejb的性能调整也是比较复杂的,而且一个设计良好的ejb和糟糕的ejb设计之间的性能差距,无论如何调整也是无法缩小的,针对ejb的调整,恐怕是需要从设计开始探讨的一个话题了,所以我在这里避开了ejb的相关话题。在was5.0中,还提供了一个“Tivoli 性能查看器”,这个查看器可以提供更为详尽的运行期信息,根据这些信息,可以更为有的放矢的调整相关设置。另外,对于ibm http server的运行期监控,比如我文中提到的连接变动情况等,主要是通过修改http server的配置文件,load几个用于监测的module来实现的,对此,在was的inforcenter中也有详尽的说明,我就不重复了。
小猪@dfw
------------------------------------------------------------------------
转载请注明出处,保持原文完整,谢谢。
 
三更半夜上网,果然没白来
save!
 
小猪,劳驾,有个问题向你请教!是关于WAS5通过DataSource与数据库连接,在应用程序获得连接时,第一次初始化,WAS连接池层在执行创建新的连接就会报错,错误是由于JTA的受管连接造成的。我到现在没有查明原因,显然是因为DataPools与DataBase Driver之间配合的问题,或者由于某个该死参数的设置问题,但是我没有查出原因。请与我联系:QQ:41639251,Mail:yongzhouli@126.com
 
很高兴看到这样的文章,我正在为我们的WebSphere 4.03的进一步调优在烦恼,我们的环境是SuSe 7.2+Db2 7.2 (DB和WebSphere会分布在两台机器上),现有程序在压力测试环境模拟中,一两百个用户就比较吃力,而我们的程序最终至少得有三百个用户
 
lyz0726:
我一直使用自己管理的连接池,对于was的连接池配置没有研究,你可以到ibm网站上下载
infocenter看看,那里面通常有比较详细的说明。
yatwql:
300个用户应该很容易满足。参照本文,应该没有什么问题:p
 
呵呵,谢谢小猪!IBM的什么资料里面都是这个样子,没说明白。我现在是必须用WebSphere的连接池数据源。不过自己写一个也是不错的主义,以前写过感觉还行:)留个联系方式吧:QQ41639251请注明大富翁
 
顶部