Nginx和Tomcat的session处理分为两步:
第一步,解决Nginx和Tomcat的负载均衡;
第二步,解决Tomcat集群和Memcached存储会话。
我们的这个案例是这样的在IP为192.168.3.139这台机器上安装了Tomcat1和Memcached1,而在IP为192.168.3.140这个台机器上安装了Tomcat2和Memcached2,对于Tomcat1和Memcached1、Tomcat2和Memcached2只是一个叫法而已,它们是完全一样的。在配置时要实现以下功能,参考了如下的官方文档:
http://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration
看下面的图:
< Tomcat1> < Tomcat2>
. \ / .
. X .
. / \ .
< Memcached1> < Memcached2>
在正常情况下,换句话说就是Tomcat1和Memcached1、Tomcat2和Memcached2都正常工作的时候,Tomcat1 会将session ID存储在Memcached2中,同理Tomcat2 会将session ID存储在Memcached1中,但是如果其中的一个Memcached出现了问题,与其对应的Tomcat就会将session ID存储在另一个Memcached中。为什么这样做呢?如果运行在同一台机器上Tomcat和Memcached同时倒掉(这种情况多数是系统崩溃)时,用户的会话不会丢失。
这样的结构实现了只要有一个Tomcat、一个Memcached不失效就可以正常工作。
第一步,解决Nginx和Tomcat的负载均衡
这一步比较简单,在Nginx的配置文件中添加如下内容:
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65;
upstream tomcat { server 192.168.3.139:8080; server 192.168.3.140:8080; }
server { listen 80; server_name localhost;
location / { root html; index index.html index.htm; proxy_pass http://tomcat; proxy_set_header X-Real-IP $remote_addr; client_max_body_size 80m; } …… }
…… }
|
然后再重新启动Nginx就可以了。
第二步,解决Tomcat集群和Memcached存储会话
这一步又分为两步来完成:一是要解决Tomcat集群,二是要解决Memcached存储会话。
第一步、解决Tomcat集群
在这个案例中我们配置了两台Tomcat服务器,在两台不同的物理服务器上,它们的IP分别为192.168.3.139和192.168.3.140。
在IP为 192.168.3.139 的机器上添加如下配置:
将以下内容添加在$CATALINA_HOME/server.xml中。
<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="224.0.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.3.139" port="4000" 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"/> </Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster> |
注意将以上的配置添加在原配置文件中:
<!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> --> |
的下面即可。
另外还需要执行以下四条命令:
[root@mail tomcat]#mkdir /tmp/war-temp/ [root@mail tomcat]#mkdir /tmp/war-deploy/ [root@mail tomcat]#mkdir /tmp/war-listen/ |
这三条命令没什么可解释的,这是上面配置中的需要。
[root@mail tomcat]# route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0 |
这条命令的功能在于添加多播路由,对于是不是eth0设备要根据具体的情况设定。
在IP为 192.168.3.140 的机器上添加如下配置:
将以下内容添加在$CATALINA_HOME/server.xml中。
<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="224.0.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.3.140" port="4000" 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"/> </Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster> |
同样,注意将以上的配置添加在原配置文件中:
<!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> --> |
的下面即可。
另外还需要执行以下四条命令:
[root@mail tomcat]#mkdir /tmp/war-temp/ [root@mail tomcat]#mkdir /tmp/war-deploy/ [root@mail tomcat]#mkdir /tmp/war-listen/ |
这三条命令没什么可解释的,这是上面配置中的需要。
[root@mail tomcat]# route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0 |
这条命令的功能在于添加多播路由,对于是不是eth0设备要根据具体的情况设定。
第二步、解决Memcached存储会话
由于我们使用了Memcached,因此需要下载它的客户端java包,如果你能够自己写,那么也可以自己去写,不过这种活我们做运维的多数是干不了,干不了就使用开源的吧,google的开源替我们做了,需要我们做的就是下载了。
下载下面的jar包,并且将其放置在$CATALINA_HOME/lib目录下,在两台装有Tomcat的机器上做同样的操作,就是说在两个Tomcat服务器的$CATALINA_HOME/lib目录下都添加以下jar包。
[root@mail lib]#wget http://memcached-session-manager.googlecode.com/ \ > files/memcached-session-manager-tc7-1.4.1.jar [root@mail lib]wget http://memcached-session-manager.googlecode.com/ \ > files/msm-javolution-serializer-jodatime-1.3.0.jar [root@mail lib] wget http://memcached-session-manager.googlecode.com/ \ > files/msm-javolution-serializer-cglib-1.3.0.jar [root@mail lib]wget http://memcached-session-manager.googlecode.com/ \ > files/minlog-1.2.jar [root@mail lib]wget http://memcached-session-manager.googlecode.com/ \ > files/msm-kryo-serializer-1.4.0.jar [root@mail lib]wget http://memcached-session-manager.googlecode.com/ \ > files/kryo-1.03.jar [root@mail lib]wget http://memcached-session-manager.googlecode.com/ \ > files/reflectasm-0.9.jar [root@mail lib]wget http://cloud.github.com/downloads/magro/ \ > kryo-serializers/kryo-serializers-0.8.jar [root@mail lib]wget http://mirrors.ibiblio.org/pub/mirrors/ \ > maven2/asm/asm/3.2/asm-3.2.jar [root@mail lib]wget http://spymemcached.googlecode.com/ \ > files/memcached-2.5.jar
|
然后再在$CATALINA_HOME/context.xml添加配置内容,两台Tomcat的$CATALINA_HOME/context.xml文件中都添加。
在192.168.3.139的机器上添加:
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.3.139:11211 n2:192.168.3.140:11211" failoverNodes="n1" requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> |
将以上的内容放置在原文件<Context> … </Context>元素之内。
在192.168.3.140的机器上添加:
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.3.139:11211 n2:192.168.3.140:11211" failoverNodes="n2" requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> |
同样添加在原文件<Context> … </Context>元素之内。
好了,现在所有的配置都完成了。