您现在的位置是:首页 > 文章详情

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

日期:2018-03-23点击:454

一、概述

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

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

Nginx+Tomcat+memcached高可用会话保持
说明:客户端请求时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> <h1><font color="red">TomcatA.san.com</font></h1> <table align="centre" border="1"> <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
Nginx+Tomcat+memcached高可用会话保持
Ctrl+F5强制刷新 又出现Tomcat B
Nginx+Tomcat+memcached高可用会话保持

引发问题:如果是两台内容一样的配置,客户端访问刷新一下就换到另一个后端处理;类似通过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.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>

复制 /etc/tomcat/web.xml /var/lib/tomcat/webapps/test/WEB-INF/ 下并在web.xml的"<web-app >"字段下添加 "<distributable/>";
重启tomcat 并再次访问http://www.san.com/test 如图:
Nginx+Tomcat+memcached高可用会话保持
Ctrl + F5强制刷新如图:
Nginx+Tomcat+memcached高可用会话保持
可以可出会话得到保持,只要是从同一个客户端中请求,刷新或关闭重新打开(基于同一个浏览器) 只要会话没有过期,会话(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)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"/> </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 如图:
Nginx+Tomcat+memcached高可用会话保持
Ctrl+F5强刷新 如图:
Nginx+Tomcat+memcached高可用会话保持

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

总结:

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

原文链接:https://blog.51cto.com/dyc2005/2090341
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章