Nginx+Tomcat+memcached高可用会话保持

文章目录

[隐藏]

  • 一、概述
  • 二、安装配置集群
  • 三、Tomcat Session Replication Cluster配置
  • 四、Tomcat Memcache Session Server高可用配置
  • 总结
一、概述

之前文章已经描述了企业高可用负载相关的架构及实现,其中常用的nginx或haproxy,LVS结合keepalived做前端高可用调度器;但之前没有提到会话高可用保持;
本文通过 Tomcat Session Replication Cluster(tomcat自带)和tomcat结合memcat及第三方组件实现Tomcat Memcache Session Server高可用会话缓存服务;
实现的效果:
同一客户端访问业务网站,经过调度器负载调度到达后端,不管选择的是那个后端,session ID都不变,都保存在两台或多台的memcached缓存中(负载冗余);以保持持会话;

架构图:

说明:客户端请求时nginx通过负载调度算法将请求调度至某一后端服务器;tomcat 把会话通过组播的方式复制到集群各节点;所有节点共享会话;

说明:客户端请求时nginx通过负载调度算法将请求调度至某一后端服务器;并把session存储到两台memcached中;客户端刷新(不换浏览器)时,请求换成另一个后端服务器响应时session ID保持不变;

测试环境:

nginx: CentOS7 epel 安装nginx WAN:172.16.3.152 LAN:192.168.10.254
tomcat A: CentOS7 node1.san.com epel 安装 tomcat 7 openjdk-1.8.0 memcached(现实环境中单独服务器)
tomcat B: CentOS7 nodde2.san.com epel 安装 tomcat 7 openjdk-1.8.0 memcached 现实环境中单独服务器)
测试客户端ubuntu 16.04

cat /etc/hosts  172.16.3.152       www.san.com  
二、安装配置集群

nginx安装

[root@nginx ~]# yum install epel-release -y  [root@nginx ~]# yum install nginx -y  

nginx配置

在/etc/nginx/nginx.conf http段添加如下行

    upstream tcsrvs {          server 192.168.10.11:8080;          server 192.168.10.12:8080;          }  

cat /etc/nginx/conf.d/san.com.conf

[root@nginx ~]# cat /etc/nginx/conf.d/san.com.conf  server {              listen 80;              server_name www.san.com;              location / {                  proxy_pass http://tcsrvs;                  }          }  

Tomcat配置:
两台均需要安装

#yum install epel-release -y  #yum install java-1.8.0 java-1.8.0-openjdk-devel tomcat tomcat-webapps tomcat-admin-webapps tomcat-docs-webapp  -y  

说明:也可以通过oracle官方下载jdk 下载tomcat 解压到指定目录并添加环境变量;一般企业推荐此种方式;为了快捷,我们用epel仓库中的稳定版本;

添加测试页

yum 安装的tomcat工作目录在/var/lib/tomcat/webapps 分别在node1与node2上,此目录下创建测试项目,title 分别叫Tomcat A与Tomcat B 颜色分别为green与red;以示区别;生产环境node1 与node2内容一致;这里为了测试区别node1与node2内容;

#mkdir -pv /var/lib/tomcat/webapps/test/{WEB-INF,META-INF,classes,lib}  #cat /var/lib/tomcat/webapps/test/index.jsp  <%@ page language="java" %>   <html>        <head><title>Tomcat A</title></head>            <body>               <h4><font color="red">TomcatA.san.com</font></h4>             <table align="centre" >              <tr>                  <td>Session ID</td>              <% session.setAttribute("san.com","san.com"); %>              <td><%= session.getId() %></td>              </tr>              <tr>              <td>Created on</td>             <td><%= session.getCreationTime() %></td>             </tr>        </table>      </body>  </html>  

配置管理页密码

tomcat与管理程序安装好后配置访问密码
修改注释/etc/tomcat/tomcat-users.xml文件

<role rolename="admin-gui"/>  <role rolename="manager-gui"/>  <user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/>  

备份默认/etc/tomcat/server.xml文件

cd /etc/tomcat  cp server.xml server.xml_def  

测试页访问

http://www.san.com/test 如图:出现Tomcat A

Ctrl+F5强制刷新 又出现Tomcat B

引发问题:如果是两台内容一样的配置,客户端访问刷新一下就换到另一个后端处理;类似通过session保留信息的服务(购买物车)如何保留?换句话说,如何保持会话不中断,无论请求被分配到那一个后端?

解决方案

1)会话sticky(粘性):分为source_ip 基于源ip和cookie

source_ip在不同的调度器上有不同的实现方式:
lvs:sh算法;
nginx:ip_hash或hash $request_uri consistent(一致性哈希算法)
haproxy: source

cookie:
nginx:hash 或 hash $cookie_name consistent;
haproxy:cookie

2)会话集群(session cluster):delta session manager

3)session server: redis(store),memcached(cache)

以下基于tomcat自带会话集群与memcached实现会话保持 功能;

三、Tomcat Session Replication Cluster配置

Tomcat Session Replication Cluster中文又叫 tomcat 会话复制集群,即会话通过组播方式复制到每一个后端tomcat节点;
可参考自带帮助文档:http://www.san.com/docs/cluster-howto.html
两台node1 node2节点/etc/hosts中添加如下:

#cat /etc/hosts  192.168.10.11 node1.san.com node1  192.168.10.12 node2.san.com node2  

两台tomcat 节点sever.xml的Host字段中添加如下内容:

<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.10.0.4"                          port="45564"                          frequency="500"                          dropTime="3000"/>              <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"                        address="auto"           <!--   如果没有/etc/hosts解析则需要本机ip   -->                        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.MessageDispatch45Interceptor"/>            </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>  

复制 /etc/tomcat/web.xml /var/lib/tomcat/webapps/test/WEB-INF/ 下并在web.xml的”“字段下添加 ““;
重启tomcat 并再次访问http://www.san.com/test 如图:

Ctrl + F5强制刷新如图:

可以可出会话得到保持,只要是从同一个客户端中请求,刷新或关闭重新打开(基于同一个浏览器) 只要会话没有过期,会话(session id) 无论来自那个后端,均是一样;

缺点:

tomcat自带支持会话集群(能过多播方式发送各节点);但有一个缺点;后端tomcat节点过多时效率低下,不适用大规模;

四、Tomcat Memcache Session Server高可用配置

原理说明:
客户端请求到达前端nginx调度器并分配到后端某tomcat节点时,tomcat会优先使用本机内存保存session,当一个请求结束后,tomcat会通过第三方组件(kryo,javolution,xstream,flexjson)把session序列化并发送到memcached节点上存放作备份,第二次请求时,如果本地有session就直接返回,第二次请求结束,把session修改后的信息更新到后端的memcached服务器,以这样的方式来保持本地的session与memcached上的session同步。当这个tomcat节点宕机时,那么用户的下一次请求就会被前端的负载均衡器路由到另一个tomcat节点上,而这个节点上并没有这个用户的session信息,这个节点就从memcached服务器上去读取session,并把session保存到本地的内存,当请求结束,session又被修改,再送回到memcached进行存放备份
当后端配置了多台memcached时,tomcat在更新session信息时会同时向多个memcached节点更新session,当一个memcached节点故障时,tomcat可以从选择一个正常工作的memcached节点读取session信息来发送给用户的浏览器,让其重置session信息,这样,memcached也达到了高可用的目的;
以下操作均在两台node上操作

还原默认配置文件

#cd /etc/tomcat/  #cp server.xml server.xml_cluster  #cp server.xml_def server.xml  #systemctl stop tomcat  

安装memcached服务

#yum install memcached -y  #systemctl start memcached  

memcache配置(默认即可,生产环境时需要加大内存与并发连接数)

# cat /etc/sysconfig/memcached  PORT="11211"  USER="memcached"  MAXCONN="1024"  CACHESIZE="64"  OPTIONS=""  

两台/etc/tomcat/server.xml Host段中添加如下内容:

<Context path="/test" docBase="test" reloadable="true">          <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"                  memcachedNodes="m1:192.168.10.11:11211,m2:192.168.10.12:11211"                  failoverNodes="m1"                  requestUriIgnorePattern=".*.(ico|png|gif|jpg|css|js)$"                  transcoderFactory/>          </Context>  

说明:

添加两个冗余备份memcached节点分别叫m1,m2 failoverNodes=”m1″ 表示m1作为备份;当m2失败时连接;即使用m2;

安装对应版本组件

下载以下JAR包到tomcat库目录;  cd /usr/share/tomcat/lib  wget http://www.java2s.com/Code/JarDownload/javolution/javolution-5.5.1.jar.zip  #需要解压 unzip javolution-5.5.1.jar.zip  wget http://repo1.maven.org/maven2/net/spy/spymemcached/2.12.1/spymemcached-2.12.1.jar  wget http://repo1.maven.org/maven2/de/javakaffee/msm/msm-javolution-serializer/2.1.1/msm-javolution-serializer-2.1.1.jar  wget http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager-tc7/2.1.1/memcached-session-manager-tc7-2.1.1.jar  wget http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/2.1.1/memcached-session-manager-2.1.1.jar  

注意:epel安装的tomcat 和openjdk版本如下:
openjdk: “1.8.0_161”
tomcat : “7.0.76”
以上第三方插件须和对应的版本是兼容的;如发现tomcat启动有问题;无法访问或如下类似错误

#tail -fn 100 /var/log/tomcat/catalina.xxxx.log  三月 23, 2018 4:12:52 下午 org.apache.catalina.core.StandardContext startInternal  严重: The session manager failed to start  org.apache.catalina.LifecycleException: Failed to start component [de.javakaffee.web.msm.MemcachedBackupSessionManager[/test]]      at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)      at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5643)      at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)  

则表示第三方组件与tomcat不兼容!请重新下载版本;

测试:
浏览器访问http://www.san.com/test 如图:

Ctrl+F5强刷新 如图:

从测试上可以看出目前已经通过memcache存储session等缓存信息;并同步到两台memcache上;当前只使用m2节点;

总结

通过nginx快速实现负载tomcat应用;引用session不可保持问题;通过自带的Tomcat Session Replication Cluster和结合memcached及第三方组件实现高可用会话缓存服务来保持会话;前者不适合大规模应用;

原文出处:51cto -> http://blog.51cto.com/dyc2005/2090341?

本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如果侵犯你的利益,请发送邮箱到 [email protected],我们会很快的为您处理。
超哥软件库 » Nginx+Tomcat+memcached高可用会话保持