最近在研究负载均衡,发现有用软件实现的,也有用硬件实现的。 在实现负载均非常重要一部就是要处理用户的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 zbc@zbc.com
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. 测试。