最近在研究负载均衡,发现有用软件实现的,也有用硬件实现的。 在实现负载均非常重要一部就是要处理用户的session,一般来说会有这几种策略:session复制,session sticky和基于cache的集中式session。在这里我用的是session复制的方式,这种方式只需在配置集群时候指明className为SimpleTcpCluster即可, 可以参考(http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html)。这种方式的优点是:当一台服务器挂掉时,其他的服务器上也有用户的session, 用户的请求不会失败; 缺点是:“the session gets replicated to all the other nodes in the cluster”这个过程浪费性能,只适用于小规模的集群。session sticky这种方式恰好与session复制的这种方式相反。
由于没有硬件资源,本文主要说明以软件方式实现的负载均衡。
1. 需要的软件环境:
1). JDK 1.7, 2). IDE(MyEclipse), 3). Tomcat 7.x, 4). Apache服务器
2. 配置项目和tomcat
1). 为需要实现负载均衡的项目的web.xml配置文件添加<distributable/>元素。
2). 配置apache tomcat
a). 修改 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />的端口号
b). 修改修改 <Engine name="Catalina" defaultHost="localhost">,在末尾添加jvmRoute="tomcat1"
c). 修改 <Server port="8010" shutdown="SHUTDOWN">的端口号
d). 修改 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />的端口号
e). 添加默认的集群配置, 参考: http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html
3. 复制一份当前的tomcat,略微修改以上的端口,命名为tomcat2(jvmRoute="tomcat2")
4. apache 负载均衡配置
1). 在安装目录下的conf/httpd.conf里面修改监听端口为 :Listen 9000,默认是80
2). 打开以下注释
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so
3). 添加代理相关的配置到httpd.conf
<VirtualHost *:9000> ServerAdmin [email protected] ServerName localhost ServerAlias localhost ProxyPass / balancer://项目名/ stickysession=JSESSIONID|jsessionid nofailover=On ProxyPassReverse / balancer://项目名/ </VirtualHost> ProxyRequests Off <proxy balancer://项目名> BalancerMember ajp://localhost:8009 loadfactor=1 route=tomcat1 smax=5 max=20 ttl=120 retry=300 timeout=15 BalancerMember ajp://localhost:9009 loadfactor=1 route=tomcat2 smax=5 max=20 ttl=120 retry=300 timeout=15 # status=+H为配置热备,当所有机器都over时,才会请求该机器 #BalancerMember http://192.168.1.11:8009 status=+H ProxySet lbmethod=bytraffic # lbmethod还可以取值: byrequests、bybusyness,上面提到的loadfactor相当于一个权重 </proxy>
5. 分别启动apache,tomcat1,tomcat2, 在项目用的index.jsp中添加如下代码:
<% out.println("<br> SESSION ID:" + session.getId()+"<br>"); String name = request.getParameter("name"); if (name != null && name.length() > 0) { String value = request.getParameter("value"); session.setAttribute(name, value); } out.print("<b>Session List:</b>"); Enumeration<String> names = session.getAttributeNames(); while (names.hasMoreElements()) { String key = names.nextElement(); String value = session.getAttribute(key).toString(); out.println( key + " = " + value+"<br>"); System.out.println( key + " = " + value); //用于查看是哪个tomcat处理的这个请求,稍后关闭这个tomcat,然后刷新页面, //看请求能否被转发到另外的tomcat上, 同时在页面上查看session内的信息是否还在 } %> <form action="index.jsp" method="post"> Session Key:<input type=text name="name"><br/> Session Value:<input type=text name="value"><br/> <input type=submit value="Submit"> </form>
6. 测试。