dev2dev 首页 > 资源中心 > 专家Blog > 专家Blog文章
关于Apache插件的问题
最近我在帮助一个客户的测试小组对他们站点上的应用程序进行负载测试和性能调优。该应用程序是在一个新近才构建的环境中交付的,而且由于该应用程序非常庞大复杂,我们计划进行冒烟测试。在前期测试中,我们逐渐升到1000个并发用户的峰值,这是该应用程序的需求标准。在冒烟测试阶段,我们试图配置不同的元素:LoadRunner、Web Servers、WebLogic和带有冗长的日志纪录的应用程序。我们还对Java进程进行定期的线程转储;WLS和其他Java应用程序也对Oracle运行stats pack,并进行跟踪。这确保了出现问题时客户机有数据库的完整跟踪记录,不会因需要更多的数据而再次运行耗时颇久的测试。
在分析第一次测试时,我们注意到,许多LoadRunner事务都失败了。详细检查LoadRunner日志后,我们发现,在事务中的特定点,虚拟用户(vuser)请求被重定向到登录页。从日志中还可以看出,JSESSIONID改变了,似乎由于某种原因,原始的JESSIONID无效了。我们知道所使用的WebLogic插件有一些已知的局限性,一般情况下我们可以使用一些操作过程绕过这些问题。但是,这一次我们的常规过程并不能缓解问题。在搜索新闻组并请教基础架构方面的专业人士后,我对引起问题的原因产生了新的思路。这些原因可能包括:
- WebLogic插件的问题。
- 软件技术近期的配置改变或阈值异常。
- 硬件网络问题。
- 以上三种情况都有。
因此我阅读了相关的Support Patterns(支持模式),并获得了BEA的支持用例。Support Patterns是一个好的起点,其中有许多有用的信息,如:如何理解日志消息,以及一些故障的常见原因。
借助于这些信息,我阅读了各种应用程序日志文件,收集所需的信息。LoadRunner日志记录可能非常冗长,它可以记录变量所代入的值以及请求和响应数据。我只对请求和响应头部感兴趣,幸好很容易配置LoadRunner场景使其满足此要求。接下来是将WL插件日志记录配置到apache代理httpd.conf文件中。为了进行全面调试,我配置了如下内容:
Debug ALL
DebugConfigInfoON
我们开始进行负载测试,果然很快就又出现问题。依照support patterns上所说的,我在wl-plugin.log中搜索X-WebLogic-Cluster-List,其结果将有助于判断是否存在组播问题。按照support patterns所说:
“通过响应流中的HTTP头部X-WebLogic-Request-ClusterInfo,处理插件请求的后端weblogic服务器返回当前它所感知的活动集群成员列表。只有在集群列表发生改变时,才会返回头部。”
下面是一个输出片断:
grep X-WebLogic-Cluster-List wlproxy.log
Mon Jul 11 10:02:34 2005 Hdrs from WLS:[X-WebLogic-Cluster-List]= [-1570623098!wls03-box1.mydomain.co.uk!7031!7032|-275029114!wls04-box1.mydomain.co.uk!7031!7032| -77678272!wls0 4-box2.mydomain.co.uk!7031!7032|1224650312!wls03-box2.mydomain.co.uk!7031!7032]
Mon Jul 11 10:02:37 2005 Hdrs from WLS:[X-WebLogic-Cluster-List]= [-212450867!wls05-box2.mydomain.co.uk!7031!7032|-556653656!wls06-box1.mydomain.co.uk!7031!7032| 154060377!wls06 -box2.mydomain.co.uk!7031!7032|2075221667!wls05-box1.mydomain.co.uk!7031!7032]
Mon Jul 11 10:02:37 2005 Hdrs from WLS:[X-WebLogic-Cluster-List]= [-212450867!wls05-box2.mydomain.co.uk!7031!7032|-556653656!wls06-box1.mydomain.co.uk!7031!7032| 154060377!wls06 -box2.mydomain.co.uk!7031!7032|2075221667!wls05-box1.mydomain.co.uk!7031!7032]
Mon Jul 11 10:02:38 2005 Hdrs from WLS:[X-WebLogic-Cluster-List]= [-212450867!wls05-box2.mydomain.co.uk!7031!7032|-556653656!wls06-box1.mydomain.co.uk!7031!7032| 154060377!wls06 -box2.mydomain.co.uk!7031!7032|2075221667!wls05-box1.mydomain.co.uk!7031!7032]
Mon Jul 11 10:02:40 2005 Hdrs from WLS:[X-WebLogic-Cluster-List]=[]
Mon Jul 11 10:02:40 2005 Hdrs from WLS:[X-WebLogic-Cluster-List]=[]
Mon Jul 11 10:02:40 2005 Hdrs from WLS:[X-WebLogic-Cluster-List]=[]
我们的基础架构有5个代理,维护着2个集群,所有这些代理日志文件中都有消息。似乎服务器列表已经被刷新了很多次,这使我如闻警钟。插件必定为维护服务器列表做了很多工作。从日志文件我们可以看出,它维护着两个集群的服务器,有时还从WLS得到空的服务器列表。使用MulticastTest实用工具,我们很快确定,另一个域中的一个集群正在使用同一个组播地址。进行适当的更改后,再次运行测试,我们注意到,错误的数目大大降低,而且在插件日志中没有找到WLS返回空服务器列表的迹象。这是好消息。坏消息是仍然有许多会话丢失故障。很明显,问题的原因不止一个。
令我烦恼的是,一旦LoadRunner vuser丢失了会话,就不再恢复了。与负责load runner脚本的人谈过后,我们认识到,之所以会这样,原因是vuser只能登录一次,然后在注销之前针对不同的业务流程迭代若干次。这是一种非常合理的实现,它反映了现实中在系统上的活动,但是在遇到像我们这样的问题时脚本却很容易出现故障。我们得出结论,必须修改脚本,使得每次迭代vuser都要登录和注销。然后我们会创建特定的“长期运行”脚本,模拟那些长时间保持登录状态处理业务的用户。我们测试了修改后的脚本,果然将错误数目由1000个降至100个。测试中,1.5个小时内我们运行了1000个vuser,生成了大约250,000个事务,此时错误率已经远远低于1%,但是对我们来说仍然太高了!
仔细思考其余错误的原因,我发现我并没有在其他站点上看到过这种错误。是否是该客户所使用的基础架构使他们容易出错?我预感到,至少基础架构的架构是其余错误的一个原因。我在其他站点上看到过向多个集群发出请求的Apache服务器代理,但是这些站点的要求要比该客户的站点低的多。我一般不喜欢这种设置,我更喜欢将Apache服务器只用于一个集群,这有许多好处:
- 提高可维护性。即代理的调试、配置和重新配置更加容易。我不喜欢费力地配置(基于某种复杂的规则)向若干个不同集群发出请求的代理的配置文件,那简直是一团混乱。
- 减少代理的工作负载。Apache也许是一个很不错的免费Web服务器。但是最好还是不要让WL插件执行复杂的任务。
- 如果您配置WL插件使其支持代理对多个集群的请求,每次更改配置时,都要考虑更改会对代理所服务的每个集群造成什么影响。这方面最好的例子是故障检修。假设您遇到了问题,需要打开插件的日志纪录,(这种情况经常会遇到),将此传递给服务交付人员将很困难,因为它会影响所有的集群。如果代理只服务于一个集群,就只对这个集群造成影响。因此将集群隔离开来是有好处的。
这样做的缺点在于成本较高。该客户在Sun spark机器上构建Apache,如果每个代理只用于一个集群,那么就需要再添加一台机器。从短期来看,添加一台机器是一个可行的选择,但是后来我们发现,这也会影响现有的系统。我的建议是,将Apache服务器移到linux机器上,这样就能负担得起了。然后Sun的机器可以安装WebLogic Server以加强现有的集群,而我们可以在这些机器上安装一些其他的Java应用程序。这些建议都是为中长期而计划的。
我迫不及待地想要测试指定的代理配置,看看它是否能改善我们的问题。幸好基础架构部门的那些家伙测试后认为这么做是值得的。在对代理进行必需的更改前,我使用代理bridge页面验证代理插件的版本。我们使用BEA方面提供给我们的Apache 1.3插件的最新版本反复测试。
测试的结果并不像预料的那样,但是经过分析之后,我们意识到我们手头另有一个问题,与此具有相同的症状。流量和性能测试被分为两条路线,A和B。路线A有3个代理,而路线B有2个。我们发现,路线A上不发生会话丢失错误,而路线B上则总是出现问题。插件日志文件报告了两个错误:
Sat Jul 23 17:59:04 2005 got exception in sendRequest phase: PROTOCOL_ERROR [line 856 of ../nsapi/URL.cpp]: Unexpected EOF reading HTTP status - connection reset at line 2981
Sat Jul 23 18:45:31 2005 *******Exception type [CONNECTION_REFUSED] (Error connecting to host xxx.xxx.xxx.xxx:xxx) raised at line 1687 of ../nsapi/URL.cp
CONNECTION_REFUSED错误几乎总是导致会话丢失,并将用户重定向到登陆页面上。故障检修模式和插件文档都提供了处理这些错误的建议,但是我打算先解决PROTOCOL_ERROR错误,然后再深入研究这些建议。我以前从未遇到过这种错误,BEA方面好像也没有说明如何解决。我求助于网络方面的人士。他们很快回复说,这正是网络安全性软件预防拒绝服务攻击时出现的错误。这给了我们很大帮助,我们并没有在路线A的3个代理上看到这种错误,因为它的流量被分到3个ip地址中。这说明没有超出主要的安全性阈值。但是同样的负载在路线B上只分到2个ip地址中,这就足以跳过网络安全性阈值,因为该阈值限制的是每个ip地址的请求速度。网络方面同意在测试期间降低安全性设置以确认是否是这个原因,结果证明确实如此。
现在只有CONNECTION_REFUSED错误了。我们在weblogic.kernel.default中调大accept backlog设置和阈值数,并重写了weblogic.socket.Muxer队列(显然,WLS没有重载,还可以处理更多的请求),问题就解决了。基础架构小组也想出了许多更好的代理配置(如:调大ConnectRetrySecs设置),但是遗憾的是,在他们进行测试之前我就离开了。
总而言之,是下面这些原因造成WL插件搜索服务器列表,重新连接其他的服务器,从而引起了用户会话的丢失:
- 可用服务器的代理插件列表过于陈旧。
- 与其他域的组播冲突。
- LoadRunner脚本。
- 高负载下的多个集群代理。
- 网络安全性软件阈值。
- WLS accept backlog和阈值队列设置。
这是我所遇到过的最让人头疼的问题之一。这个问题在该客户的站点上已经出现了至少两年,但是因为有操作工作区和相对较低的流量,该问题一直不是很严重。这种问题只有在客户请求流量达到一个相当高的值后才会变得非常明显。
评论
- 我不是要批评该插件,而是想说明它很容易被误用。后来BEA方面的支持人员告诉我,Apache 2版本的插件将会支持多个集群,但是我还是不主张那样做。
澄清一下,我并不是建议在调试模式下运行负载测试。我运行冒烟测试的原因是,只有在高负载下问题才会重现。
发表人:hoos,2005年8月10日,10:44 AM
- 那些代码是5年前编写的,而且经过了多次修改以增强和提高。它肯定会有它的辉煌时期和黑暗时期(它太复杂了,不适合再进行维护)。有些客户喜欢它,有些则不。不管怎样,许多人将其用到了生产中。我已经很久没有留意这个代理插件了。但是我记得,我们最初设计它时,并不是用来支持多个集群的。另外,也不应该在调试模式下进行负载测试。
发表人:jlee,2005年8月10日,09:34 AM
原文出处:
http://dev2dev.bea.com/blog/hoos/archive/2005/08/apache_plugin_w.html
作者其它文章
|