apche2+tomcat使用modProxy方式 实现负载均衡
一.要是在负载均衡,首先得实现应用服务器之间的session的复制!
1) 这要求所有放在session里的数据对象都必须实现Seriolizable接口!
2) 修改tomcat的server.xml,在<Engine>节点下添加:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" [color=red]port="4000"[/color] autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/><Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>
如果是在同一台机器上的多个tomcat,请修改上面Cluster标签内的红色部分的端口号,保证不重复!
3.修改您的项目的web.xml,在最下面加入'<distributable/>';
4.在server.xml中修改engine节点,如下
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
5.还要注意,如果有多台机器的话,那么机器间的时间必须同步!否则session复制会出问题!
6.当然别忘了修改server.xml中http port ,同一台别重复!多台机器间可以重复!下面shutdown端口如果是同一台机器也得改一下!
<Server port="8006" shutdown="SHUTDOWN">
通过以上6步,我们就实现了不用应用间的session复制,下面进行测试,放出测试页面test.jsp:
<%@ page contentType="text/html; charset=GBK" %> <%@ page import="java.util.*" %> <html><head><title>Cluster Test</title></head> <body> <% //HttpSession session = request.getSession(true); System.out.println(session.getId()); out.println("<br> SESSION ID:" + session.getId()+"<br>"); // 如果有新的请求,则添加session属性 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 sname = names.nextElement(); String value = session.getAttribute(sname).toString(); out.println( sname + " = " + value+"<br>"); System.out.println( sname + " = " + value); } %> <form action="test.jsp" method="post"> 名称:<input type=text size=20 name="name"> <br> 值:<input type=text size=20 name="value"> <br> <input type=submit value="提交"> </form> </body> </html> 之后启动不同的tomcat服务,观察session参数是否同步,成功的话,代表session复制成功!
二.负载均衡的实现
1)apche2.2以上版本的安装.
2)tomcat 的 server.xml的修改:
Tomcat7配置,因为是同一机器,两个应用,所以配不同的端口,不同机器则不用配,要和前面的ajp对应上。
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Connector port="9009" protocol="AJP/1.3" redirectPort="8443" />
3)apache httpd.conf的修改,如下:
# 监听端口和监听地址 Listen 8000 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 #mod_balancer管理应用 <Location /balancer-manager> SetHandler balancer-manager Order Allow,Deny Allow from all </Location> #虚拟机配置,负载均衡配置 <VirtualHost *:8000> ServerAdmin zwei5686@163.com #域名 ServerName localhost ServerAlias localhost #小心,有些地方要有空格,要不然会出错哈哈。 #examples是项目应用名称 ProxyPass / balancer://examples/ stickysession=JSESSIONID|jsessionid nofailover=On ProxyPassReverse / balancer://examples/ #ErrorLog "logs/error.log" #CustomLog "logs/access.log" common </VirtualHost> #The ProxyRequests directive should usually be set off when using ProxyPass. ProxyRequests Off <proxy balancer://examples> #这里的端口号 8009 是我在tomcat 的server.xml 中设置的#<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 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.218:8009 status=+H ProxySet lbmethod=bytraffic </proxy>
通过以上实现,负载均衡,下面进行测试:
访问 http://localhost:8000/examples/test.jsp ,会看到访问了2个不同的应用!当然测试的前提是apche服务开启!
三.其他关于负载均衡的策略问题,本文不做讨论!