tomcat的高可用与负载均衡
nginx+tomcat+memcached
主机角色:node1: 192.168.0.104:nginx tomcat memcached node2: 192.168.0.144:tomcat memcached 软件下载:http://www.nginx.org http://code.google.com/p/memcached-session-manager/
系统环境:rhel6 x64 selinux and iptables disabled
<T1> <T2> . \ / . . X . . / \ . <M1> <M2> Tomcat-1 (T1) 将 session 存储在 memcached-2 (T2)上。只有当 M2 不可用时,T1 才将 session 存 储在 memcached-1 上(M1 是 T1 failoverNode)。使用这种配置的好处是,当 T1 和 M1 同时崩 溃时也不会丢失 session 会话,避免单点故障。
首先,安装tomcat,memcached(之前有详细的安装过程,这里不讲了)
session 的序列化方案官方推荐的有 4 种: 1. java serialization 2. msm-kryo-serializer 3. msm-javolution-serializer 4. msm-xstream-serializer 其中性能最好的序列化方案是 Kryo,此实验我们采用 kryo 方式。
把如下软件包放置到/usr/local/tomcat/lib 目录中 kryo-1.03.jar kryo-serializers-0.8.jar memcached-2.5.jar memcached-session-manager-1.5.1.jar memcached-session-manager-tc7-1.5.1.jar minlog-1.2.jar msm-kryo-serializer-1.5.1.jar reflectasm-0.9.jar
<Context> ...... <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.0.104:11211,n2:192.168.0.144:11211"
vi /usr/local/tomcat/conf/context.xml 第一台机子192.168.0.114
在里面添加failoverNodes="n1" //这项表示最终访问的node,t1默认访问的使n2,当n2不能访问时,访问n1
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> </Context>
第二台机子192.168.0.144
在里面添加,将failoverNodes="n2" 修改。。。
<Context> ...... <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.0.104:11211,n2:192.168.0.144:11211" failoverNodes="n2" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> </Context>在两台机子上面同时开启memcached
memcached -u root -m 50 -d //-u指定用户 -m指定memcache大小。。。
做完之后可以用一下页面进行测试
以下为测试页面,保存到/usr/local/tomcat/webapps/ROOT/test.jsp
<%@ page contentType="text/html; charset=GBK" %> <%@ page import="java.util.*" %> <html><head><title>Cluster App Test</title></head> <body> Server Info: <% out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%> <% out.println("<br> ID " + session.getId()+"<br>"); String dataName = request.getParameter("dataName"); if (dataName != null && dataName.length() > 0) { String dataValue = request.getParameter("dataValue"); session.setAttribute(dataName, dataValue); } out.print("<b>Session list</b>"); Enumeration e = session.getAttributeNames(); while (e.hasMoreElements()) { String name = (String)e.nextElement(); String value = session.getAttribute(name).toString(); out.println( name + " = " + value+"<br>"); System.out.println( name + " = " + value); } %> <form action="test.jsp" method="POST"> name:<input type=text size=20 name="dataName"> <br> key:<input type=text size=20 name="dataValue"> <br> <input type=submit> </form> </body> </html>
测试结果
当t1挂掉时,t2能够正常工作,n1,n2正常,t2可以从n1,n2中正常取数据(t1挂掉后,t2主要是在n2中取数据,因为之前t1存储的数据是在n2中。。数据正常。。。)
当t2挂掉时,t1正常,n1,n2正常,同上
当n1挂掉时,t1正常,t2正常,n2正常,t1,t2都在n2中存储数据。。
当n2挂掉时,其他正常,同上
当t2,n2同时挂掉时,t1,n1正常,t1在n1中存储数据,数据正常(因为此时t1中的tomcat中有缓存数据)