在使用TUXEDO的过程中,会遇到一些并发请求量很大的情况,比如某些帐单处理服务或者是在营业下班前的日操作清单服务。这时,一些SERVICE会接收到大量客户端,甚至长时间的请求,对service,甚至整个系统是严峻的考验。遇到这种情况,单个的server往往难以应付,或者性能不好,我们就想到负载均衡或者使用TUXEDO的MSSQ(Multi Server, Single Queue)。下面笔者根据自己在TUXEDO应用开发和管理配置方面的实践,结合实际系统压力测试的结果对相关的问题进行一些探讨。
在没有负载均衡的情况下,是由一个server(可能包含一个或多个service)来处理客户端对其中service的请求,所有的请求首先放入这个server的队列里面,然后server逐个取出处理。在UNIX系统上,TUXEDO较多的使用了队列,并且也用到了共享内存和信号量,相关的UNIX系统参数会影响到系统的性能,但这个不在本文讨论范围之内,这里假设已经调到了合适的范围,具体请查阅TUXEDO关于IPC的文档。
现以一个帐单处理的server为例,负载均衡前server的ubb配置为:
billpay SRVGRP=GROUP1 SRVID=1
在单个server不能满足性能要求的情况下,就考虑采用TUXEDO的负载均衡方法。
方法一是直接将相关server启多份,将上面的配置改为:
billpay SRVGRP=GROUP1 SRVID=1 MIN = 5 MAX = 10
这样tmboot的时候,就会有MIN = 5个billpay启动,类似下面的情况:
billpay 00001.00001 GROUP1 1 0 0 ( IDLE )
billpay 00001.00002 GROUP1 2 0 0 ( IDLE )
(依此类推,共5个)
其中第二列是该server的队列名,"."前面是GRPNO,后面是SRVID,每个server有自己的队列。相关的另一个参数就是在ubb的*RESOURCES段的LDBAL,表示是否启动Load Balancing,默认是"N"(不启动),你可以通过设置成"Y"来启动。这里需要注意的是,为"N"的时候并不表示多个server不能分担负载。主要的差别是为"Y"时,TUXEDO在接收到请求时会按照它的负载均衡的算法来找到合适的server来处理,而设置成"N"时,总是由第一个可用的server来处理。通过这种方法可以让多个server来处理大量并发的请求,就达到了改善性能的目的。
方法二是采用MSSQ(Multi Server, Single Queue),顾名思义,就是有多份server,但是只有一个队列(请求队列)。具体的配置是:
billpay SRVGRP=GROUP1 SRVID=1 MIN = 5 MAX = 10
RQADDR=" billpay" REPLYQ=Y
启动后的情况如下:
billpay billpay GROUP1 1 0 0 ( IDLE )
billpay billpay GROUP1 2 0 0 ( IDLE )
(依此类推,共5个)
我们发现几个billpay server都关联相同的名为billpay的队列,这就是所谓的Single Queue。
与直接多server相比,多了两个参数,RQADDR是这多个server共用的队列名,是一种逻辑名,可以自己命名,不和别的冲突就可以,REPLYQ是标示是否设置返回队列,在使用MSSQ的时候是强烈建议设置,因为这样可以将请求和返回分开,避免多个server共用队列时造成混乱。相关的其它参数这里没有详细列出。
到底两种方式和没有负载均衡时有什么不同,后面将提供相关的测试结果。先分析一下两种方法。方法一有多个队列可以容纳请求,但是这些大量的请求怎样放入这些队列必定有一定的策略,而且根据LDBAL的设置会不同,但是这个策略本身的运算也是一种消耗,因为每个请求都面临着这个选择。因为这种情况下每个队列是和server对应的,所以队列的选择就意味着选择了相应的那个server,这样大量的请求就被分流。虽然有选择的消耗,但是额外的好处也是显而易见的,那就是有多个queue可用,有效避免了请求并发量很大时队列的溢出,这种情况在实际的压力测试中发生过。使用方法二时,放入队列时不用做选择,然后每个server的任务就是从队列取出请求去处理,考虑到多个server并发取队列,所以用MSSQ时其server的数目不宜太多,官方文档建议2-12。而且在这种情况下,建议不要设置LDBAL=Y,因为MSSQ本身就是一种基于single queue的负载均衡的方法,这时再使用系统的策略已经没有意义。这种方法也有一个问题,如果相对于请求数来说,处理得不够快,就比第一种方法更容易造成队列溢出。
因为我们无法知道TUXEDO一些具体的算法和策略,那就用一些具体的测试来比较吧。笔者在一个和实际生产系统配置相同的UNIX+ORACLE+TUXEDO8.0系统上做了一下试验,被测服务是一个帐单查询服务,每次根据一批ID从数据库查询出具体的帐单,由于都是实际数据和实际使用的服务,有一定的说明力,但是也不排除一些情况造成的误差。以下是测试的一些结果,每个server的实际运行份数都是10。
一:客户端数目为1,循环调用100次。
1.方法一,LDBAL = Y or N。结果发现所有的请求都由其中的一个server处理,其它全部空闲。在此基础上再进行两次循环调用,结果还是一样。
2.用方法二,LDBAL = Y or N。其中两次测试的情况是:
<1>19,19,2,2,1,18,18,1,1,19
<2>23,8,23,23,23,(其它空闲)
以上数据说明了两种方式的调度策略是不一样的,在单客户端循环的情况下方法二更合适。
二:客户端数目50,每个循环80次,统计总的执行时间。
1.用single server。两次测试的处理时间分别是219s和196s。
2. LDBAL = Y 方法一:三次测试时间为:63s,79s,69s
3. LDBAL = N 方法一:三次测试时间为:74s,79s,85s
4. LDBAL = Y 方法二:三次测试时间为:74s,73s,77s
5. LDBAL = N 方法二:三次测试时间为:78s,76s,75s
通过以上数据可以看出不管用那种方法,使用负载均衡相比单个server都可以在大量请求并发时得到更好的性能。但是同时也发现后四种情况的总时间差别不大,考虑一些实际的误差,很难断定哪种更好。
通过前面的分析,并查阅相关的文档,建议采用的是两种方式:多个server,不用MSSQ,设置LDBAL = Y;用MSSQ,设置LDBAL = N。当然,在使用TUXEDO的应用系统中,不能绝对的说哪一种方式更好,只能是根据具体的情况来分析,并通过实际的压力测试来进行选择,而且这个和具体server的特点也是有关的。