WebSphere 中池资源调优 - 线程池、连接池和 ORB
来自:https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1106_zhuxl_websphereenhancement/1106_zhuxl_websphereenhancement.html
IBM WebSphere Application Server (以下简称 WAS)能支持的应用程序越来越多,而这些应用程序有各自的独特特性、需求和服务。正如任何两个应用程序都不会采用完全相同的方式来使用应用服务器一样,我们也无法通过一组调优参数来为任意两种不同的应用程序提供最佳性能。本篇文章将重点放在 WebSphere 服务器中各种池资源的调优上,重点向读者介绍线程池、连接池和 ORB 的作用以及调优的基本准则,通过本篇文章,读者会对 WAS 调优有更加精确的掌握,特别是对各种池资源配置的了解会更加深入。从而能使自己更加有效率的使用 WebSphere 服务器。
0 评论
朱 修磊, 软件工程师, IBM
2011 年 6 月 13 日
- 内容
免费下载:IBM? WebSphere? Application Server 试用版 |
---|
下载更多的IBM 软件试用版,并加入IBM 软件下载与技术交流群组,参与在线交流。 |
WebSphere 性能优化概述
是什么引起了性能问题?或者如何提高系统的性能?这是我们在系统的开发和维护时经常会碰到的问题,但是这两个问题很难回答。正如下图所示,性能问题可能发生于系统的各个环节中,当性能问题出来后很难马上就定位性能的瓶颈在哪里,即使找到了性能瓶颈,在进行调优的时候也要考虑系统整体环境,从上下文中分析,确定调优的策略;系统中一个或者多个“短板”的存在,就能让系统无法达到设计时的目标,无法达到预期的性能提升。
在本文中,我们将重点放在 WebSphere 中各种池资源的调优上,包括线程池、数据库连接池以及 ORB 的连接数调优。池(Pool)是 WebSphere 中最常涉及的概念之一。从网络、Web服务器、Web 容器、EJB 容器,一直到数据源,每一个环节都有线程池、连接池的影子。这些池资源从上到下被连接在一起,就形成了一个访问和应答的队列。在 WebSphere 的调优中,如果能合理的配置这些池资源,可以从很大程度上提高整个系统的运行效率。
图 1. 性能问题发生在 WAS 和操作系统的各个环节中
WAS 性能差的几种表现及解决方法
系统性能差一般有以下两种非常明显的表现形式,第一种是 CPU 使用不高,用户感觉交易响应时间很长;第二种是 CPU 使用很高,用户感觉交易响应时间很长。对于第一种情况,可以断定是由于系统的某一小部分造成了瓶颈,导致了所有的请求都在等待。简单举例来说,线程池的数量开的太小,导致所有的请求都在排队等待进入线程池,因为没有可用的线程使用,所以这个交易请求一直在排队,导致交易响应时间很长。如果数据库连接池开的太小,也会有同样的表现。对于第二种情况,比较复杂。可能的根源之一是硬件资源不够。根源之二是应用系统中产生了多个大对象。根源之三是程序算法有问题。解决思路如下: 用性能分析器,如 RAD 或 JProfiler, 对运行环境进行分析,分析哪个类甚至于哪个函数消耗了这么多的 CPU,并找到相应的解决方案。
WAS 性能调优没有捷径和魔术,因为每一个应用都有自己独特的特性和资源需求,而且他们使用 WAS 的资源也有各种不同的方式,每一套调优的参数和策略仅适用于当前的系统环境,在实际的系统环境中不能简单的将一种调优策略原封不动的移植到另外一个系统环境中,这样往往得不到预期的调优目的,还可能照成更多的性能瓶颈。
WebSphere 系统队列介绍和调优
WAS 是由一系列相互作用的组件连接而成的,必须对这些被连接在一起的组件进行合理的调优,才能够满足客户的应用对系统性能的要求。这些调整和调优将帮助系统达到最大的吞吐率和最高的使用效率。
WebSphere 排队网络
当客户端发出一个请求时,该请求会从网络端开始依次进入 WehSphere 服务器的各个组件,这些请求会在各个组件中进行排队等候使用服务器资源或者等待进入下一个组件进一步被服务器处理请求,每个组件里的请求组成请求队列,而组件依次排列,就够成了 WebSphere 排队网络。正如下图所示,该排队网络包括互联网、Web 服务器、Web 容器、EJB 容器以及数据库端的连接池队列等等。WebSphere 队列里的各个组件是互相资源依赖的,对请求的平均服务时间依赖于服务器队列中每个组件在同一时间的最大并发数。
图 2. WebSphere 排队网络
保守队列和开放队列
在组成 WebSphere 排队网络的队列中,大部分都属于保守队列。对于保守队列,我们可以设置某些参数来限制队列中请求被处理的最大并发数,相反,开发队列则没有这样的限制。与开放队列相比,保守队列的好处是,可以使系统资源被有效的管理和利用,避免因为资源耗尽而引起的系统崩溃。例如,在 Web 容器中,假设平均处理一个 servlet 请求要创建 10M 大小的对象,如果我们设置其最大连接数是 100,那么这样就可以将 Web 容器对内存的最大消耗控制在 1G 左右。因此,保守队列使得系统管理员更有效的管理系统应用。
保守队列中的用户请求有两种状态,分别是激活状态和等待状态。当请求处于激活状态时,表明该请求正在被服务器进行处理;当请求处于等待状态时,表明该请求还未被处理,而是在等待被激活,进而才能够使用服务器资源。只有当一个处于激活状态的请求被处理完毕离开队列后,才会有一个处于等待状态的请求被激活,否则该请求将一直处于等待状态,直到服务器超时抛出异常,如果出现此种情况,则表明服务器需要进行系统优化。
在 WebSphere 服务器的队列网络中,Web 服务器、Web 容器以及数据库连接池都属于保守队列。EJB 容器则继承了对象请求代理(ORB)的队列特性,属于开放队列。
WebSphere 中的队列调优和设置
在 WebSphere 中,我们主要通过最大和最小连接数两个参数来对其队列进行调优和设置,接下来我们会给出一个在进行 WebSphere 队列调优时的基本准则。读者在以后的调优中可以参照这个准则,然后结合自己的实际系统环境来进行队列调优。
“漏斗”原则
WAS 调优的第一原则就是漏斗原则。一般来说,让客户不能及时得到处理的请求在网络中等待,比让它们在 WebSphere 服务器中等待要好。下图的设置使得只有即将被服务器接受处理的请求才能进入 WAS 的排队网络,这样更能提高服务器的稳定性,而不至于当大量请求突然进入 WAS 时引起资源耗尽的情况。要实现这个原则,那么越往下游的组件,其处理请求的最大并发数应小于上游组件的最大并发数。如下图所示,只有可以被处理的请求才会进入相应的组件被处理,而大于该组件并发数的其他请求,则都处于排队状态,等待服务器接受处理。
图 3. Upstream queuing
在上图的例子中,我们可以看出,在 WebSphere 排队网络中,从上到下队列中处理请求的并发数越来越小。当 200 客户端请求到达 Web 服务器的时候,因为 Web 服务器设置了自己的最大并发数是 75,所以剩下的 125 个客户请求只能暂留在网络中进行排队等待被 Web 服务器处理;当这 75 个请求经过 Web 服务器被处理后,其中 25 个仍在停留在 Web 服务器中排队,而剩下的 50 个请求则进去 Web 容器被进一步处理;直到最后有 25 个请求到达最后的数据库端,这时请求被处理完毕。在这个系统中,每一个组件都在充分的工作,没有因为等待请求到来而造成的资源浪费,因为在任何一个时刻,每个队列里都有少量请求在等待着被下一个组件处理。因为大量的请求被阻止在 WebSphere 服务器的外面(网络),所以 WebSphere 的各个组件不会因为大量请求同时到来而引起资源耗尽,这样的设置增加了系统的稳定性。
绘制吞吐率曲线
上面介绍了在对 WebSphere 服务器池资源进行调优时的一个最重要的准则,下面我们来介绍如何根据这个准则,并结合用户实际的系统环境来进行调优设置。首先我们需要画出系统在运行时的吞吐率曲线,要完成曲线,需要准备一个测试用例,然后将系统运行起来,我们的目的是要将系统的潜能发挥到最大,即系统运行达到一个资源利用的饱和点。系统运行达到饱和点最有代表性新的特征就是 CPU 的利用率接近 100%。
在运行测试用例的开始阶段,我们将 WebSphere 排队网络中所有的队列并发数都设置为一个较大的值,而且各个队列的值也设成是相等的。要保证这样的设置可以使你的系统在运行时达到最大的处理能力。例如,将排队网络的每一个队列的最大并发数都设置成 100。
现在,我们开始进行一系列的测试,根据测试数据绘出吞吐率曲线。在每一次的测试后,增加用户并发数,迭代测试,例如:把用户并发数设置成如下一组数值进行一系列测试(1,5,10,25,50,100,150,200...),在每次测试后,记录下本次系统的吞吐率和响应时间,就得到了类似于下图的吞吐率曲线。
图 4. 吞吐率曲线
吞吐率是 WebSphere 服务器在同一时间处理用户请求的并发数,反应的是 WebSphere 处理并发请求的能力。从上图中我们可以看出,曲线可以分为三个阶段,在第一阶段,也就是 A 阶段的时候,这时并发的数量比较少,吞吐率随着并发数目的增加而增加。因为在这个时候,并发数较小,队列中几乎没有请求在排队,每当一个请求到来时就能立刻得到处理,随着并发数的增加,在某一时刻,排队情况开始出现,吞吐率曲线的增长变的缓慢,直到达到了系统处理能力的饱和点,这个时候也就是出现了系统的性能瓶颈。最具代表性的系统瓶颈是,在饱和点时,系统 CPU 利用率几近 100%,这时我们只要换上更加高性能的 CPU 就可以提高整个系统的性能。在经过饱和点后,吞吐率曲线进入第二个阶段 B,这时,随着并发数的增加,吞吐量并没有增加,而是维持在一个稳定的水平。然而,客户端所感受到的服务器响应时间则会随着并发数的增加而加长,这时因为很多的请求都在队列里排队,并没有及时的被服务器处理。此刻,并发数继续增加,就会进入第三个阶段 C,这时,随着并发数的增加,吞吐率反而会急剧下降,这时因为系统中某一个组件负载过重,导致资源已经被消耗殆尽。
在进行曲线绘制的过程中,我们需要注意一个问题,如果在饱和点出现的时候,系统的 CUP 利用率接近 100%,那么我们就能进行进一步的调优设置了;如果 CPU 利用率没有达到 100%,那么就说明,系统中所运行的应用程序存在问题,也就是性能瓶颈所在。比如,你的应用程序可能创建了很多的大对象,导致了 JAVA 中的频繁 GC,大量占用系统资源而出现性能瓶颈,对于性能瓶颈,我们需要认真检查程序源代码,找出问题所在,然后修改排查,消除因为应用而造成的系统瓶颈。找出性能系统瓶颈的方法很多,不是本文论述的重点,读者可以参考其他资料来进行排查。
队列初调
在吞吐率曲线达到饱和点时的用户并发数是系统应用所能处理的最大并发数,这也是 A 阶段和 B 阶段的分界线。这个值将做为我们调整队列大小的一个基准值。如上图所示,饱和点时,并发数是 50,我们选择 48 来做为调整队列的基准值,因为在此刻吞吐率和响应时间都是最佳的,这个值称为程序所能处理请求的最大并发数。正如我们前面所介绍的,理想的情况是确保大量的等待请求处于网络中,而不是 WebSphere 服务器中,所以参照“漏斗”原则,我们可以对 WebSphere 服务器中的各个组件的最大并发数进行如下设置:Web 服务器 , 75,Web 容器 50,数据库连接池 45。然后我们在进行一系列的测试,对这些值进行微调,以使系统的性能达到最优。
根据应用的实际情况来调整队列
仅仅根据上面的准则来调优 WAS 是远远不够的,我们还应根据应用的使用环境和访问模型来调整各个队列的大小。并不是所有的请求都会从上一个队列进入到下一个队列中,比如,有些请求可能在经过 Web 服务器处理后就返回给客户端了,因为这些用户仅仅是想请求一些静态的页面内容,这时我们可以将 Web 服务器的队列值设的大一些,我们上面将 Web 服务器设成 75 就是这样的考虑;又比如,如果在一个应用中,大部分的请求都需要进行复杂而耗时的数据库操作,这时我们就应该考虑同时加大数据库连接池和 Web 容器的队列值大小。所以,在我们实际的调优中,必须结合具体的应用来确定合适的值,并在不断调整的过程中,监控 CPU 和内存的使用,避免系统资源耗尽的情况出现。
WebSphere 池资源调优的最佳实践
我们在这里给出 WebSphere 池资源调优的一些建议,但真正合适的大小还要参考实际情况,调优是一个循序渐进的过程,需要经过不断的尝试和修改才能最终达到系统设计所需要的最佳性能。
ORB 调优
当配置 ORB 线程池的时候,需要了解 EJB 客户端对应用的访问模式。比如,如果在一个 servlet 中只是有很少的 EJB 调用,而且每一次方法调用的时间相对很短,那么你就应该调整 ORB 线程池的值尽量小于 Web 容器的最大并发数。
图 5 . EJB 调用模式
并行调用 EJB 的 servlet 的数量和每次方法调用所持续的时间是我们调整 ORB 线程池大小的两个依据。如上图,是两种在 WAS 里从 servlet 中调用 EJB 的场景。第一种场景中,servlet 主要做一些持续时间非常短的远程调用,servlet 可以重用已经存在的 ORB 线程。在这种情况下,ORB 线程池可以设的比较小,例如只要设置为 Web 容易最大并发量的一半就行;第二种场景中,持续时间比较长的 EJB 调用将会长期的占用 ORB 连接,因此该连接被重用的机会很小,所以在这种场景中,最好将 ORB 线程池的大小与 Web 容器的最大并发量设置成相等,或者更大。可以使用 WAS 管理控制台进行 ORB 线程池的配置,位于 Application servers > AppServer name > Thread pools > ORB.thread.pool
Web 容器线程池
一般来说,每个服务器 CPU,5 至 10 个线程将会提供最佳吞吐量。另外我们也可以利用 WAS 自带的 TPV 来帮助我们设置 Web 容器线程池。对系统做一个压力测试,保持一定的负载,观测 TPV 中的PercentMaxed
和ActiveCount
的值,PercentMaxed 表示所有线程被使用的平均百分比,如果该值较大,那么就应该增大线程池的值;ActiveCount 表示被激活的线程个数,如果该值远小于当前线程池的大小,那么可以考虑减小线程池的值。可以
使用 WAS 管理控制台进行 Web 容器线程池的配置,位于 Application servers > AppServer name > Thread pools > WebContainer
数据库连接池
当我们连接任何数据库时,数据库连接的初始化是一个非常耗资源的操作,所以当性能问题出现时,只是一味的加大数据库连接池往往并不能提高性能。通常的做法是,首先将数据库连接池的大小增大一倍,看看是否可以解决性能问题,如果可以,再逐步减少数据库连接池的值,找到性能瓶颈以及达到最优性能时连接池的大小。一般来讲,数据库连接池的值小于 Web 容器线程池的值是比较好的选择。
在实际的环境中,我们可以利用 TPV 去监控数据库连接池的使用情况,以此来调整数据库连接池的大小,从而确定最优的调优策略。可以从 TPV 的以下监测值中寻找答案。
表 1. TPV 监控列表
监测值名称 | 描述 | 调优策略 |
---|---|---|
PooSize | 连接池的大小 | PooSize 会随着新连接的建立而增加,会随着连接的销毁而减少;应该为连接池设立一个最大值。 |
PercentUsed | 连接池线程被使用的百分比 | 如果该值长时间都很小,那么你应该调小 PooSize,反之应该增大。 |
WaitingThreadCount | 单位时间内正在等待建立数据库连接的线程的个数 | 系统最佳的性能体现在该值总是保持在很小的数目,如果该值偏大,则需要对系统进行调优 |
PercentMaxed | 数据库所有连接都被使用的时间所占的百分比 | 确保这个值不会长时间的达到 100%,如果是那样,那么你该考虑增大 PooSize 值 |
可以使用 WAS 管理控制台进行数据库连接池的配置,位于 JDBC providers > Provider name > Data sources > Data source name > Connection pools
结束语
在本文中,我们详细的讨论了 WebSphere 服务器中池资源的概念以及调优,并在介绍 WebSphere 排队网络的基础上,阐述了如何在实际的生产环境中进行池资源配置。通过阅读本文,读者可以基本掌握 WebSphere 性能调优的一般准则,并能初步掌握性能优化的一些技巧和方法。