[转]用Apache Proxy Bal…

来源:互联网 发布:室内装修设计图软件 编辑:程序博客网 时间:2024/06/08 10:50

原文来自: http://hi.baidu.com/zzeric/blog/item/1e306912aac94350f919b878.html

 

公司现在的项目一般直接用Tomcat作为Web服务器,这里要讲的并不是Apache和Tomcat的整合,而是用ApacheProxy Balance实现多Tomcat服务,提升单服务器的负载能力。

   用单个Tomcat作为Web服务器提供服务时,往往能承受的负载压力比较低,这里面有部分原因是因为单个Tomcat在SocketIO处理方面有比较明显的瓶颈(一般LoadRunner测试反映的极限是300并发vUser)。因此,可以考虑通过ApacheProxy Balance + AJP实现多个Tomcat同时提供服务,降低每个Tomcat的处理压力,避免出现瓶颈。

   我自己做了一个简单的压力测试,场景是一个用户登录的用例,包括一个login.jsp和一个login_action.jsp。login.jsp就不细说了,以下是login_action.jsp的代码

<%
if(request.getParameter("reset") != null)
{
n = 0;
maxtt = 0;
return;
}
Thread.sleep(1500);//模拟压力,对于压力越大的处理逻辑,可以增大sleep时间。
long t1 =Long.parseLong(request.getParameter("time1"));//time1是从login.jsp传过来的
long t2 = System.currentTimeMillis();
long tt = t2 - t1; //本次的处理时间
if(tt > maxtt)maxtt = tt;//更新历史最长处理时间
handleTimes ++;//更新handleTimes
System.out.println("welcome [" + handleTimes + "][" + maxtt + "]" +request.getParameter("username") + "==" + tt);//后台打印
%>
<%!
static long handleTimes = 0; //统计到达本Tomcat的次数,看看负载是否均衡
static long maxtt = 0; //记录最长的处理时间
%>

LoadRunner做的压力测试表明单个Tomcat的时候,当在300虚拟并发用户时(每个用户重复点击4次)以下时,不会出现失败或错误的事务。但当虚拟用户增大到400或500时,则会出现5%~1x%的失败或错误事务。而用ApacheProxy Balance测试的时候,则在500虚拟用户时还是没有失败或错误事务,平均响应时间比单Tomcat要快60%。

以下是Apache的部分配置
ServerName host.com
ProxyPass / balancer://proxybalancer/
ProxyPassReverse / balancer://proxybalancer/

<Proxybalancer://proxybalancer>
BalancerMember ajp://host1.com:8009
BalancerMember ajp://host2.com:8019
</Proxy>

注意:以上配置时,Apache是动态为每个请求分配转发的服务器的,也就是所说的“非stickysession”模式,例如可能你访问login.jsp时是到host1.com,提交时的login_action.jsp可能就到了host2.com。这样的处理,则要求Web程序需要满足SNA架构的要求,即Web服务器不通过其本身的session保存或传递数据。以我login_action.jsp里要计算处理时间的情况为例,一开始我是在login.jsp里把开始时间存放到session里,然后在login_action.jsp取出来进行比较,这就违反了SNA的原则。当在“非stickysession”模式下,程序就会出问题。因此,我后来改为通过queryString的方式传递开始时间,则程序可以很好的运行。

如果已有的程序无法保证符合SNA的原则的话,可以把Apache配置成“sticky session”模式。

ServerName host.com

ProxyPass / balancer://proxybalancer/stickysession=JSESSIONID
ProxyPassReverse / balancer://proxybalancer/

<Proxybalancer://proxybalancer>
BalancerMember ajp://host1.com:8009 route=host1
BalancerMember ajp://host2.com:8019 route=host2
</Proxy>

session sticky,其原理是tomcat实例response的时候,在sessionid后面附上了一个自己实例的标示(route),那么客户端浏览器再后续请求的时候,会把sessionid送过来,同时也带上了这个标示(route),apache会从sessionid这个HTTPHEAD里面拿到这个标示,决定将请求转发给后面哪个tomcat实例。因此要点就是:

1、tomcat实例要在response的时候标示自己,通过server.xml里面Engine节点的jvmRoute参数,如上例里的host1和host2,在相应的tomcat实例host1.com里面jvmRoute参数配置“host1”,在host2.com;里面配置host2。

2、apache要从request里面拿出来route信息,从哪个HEAD里面拿?通过ProxyPass命令的stickysession参数来指定

3、apache怎么转发?通过BalancerMember命令的route参数来指定。第一次分配服务器时,Apache会标记这个客户端是用哪个route标记的服务器,以后分配转发服务器时都会分配到相同的服务器。

据说apache2.2的load balance的sessionsticky性能并不好,因为他这是在七层协议级别进行请求的分发,并不很稳定,因此如果可以的话,尽量满足SNA吧,好处多多,可以很方便的通过LoadBalance来实现集群。

原创粉丝点击