分布式Session共享解决方案「建议收藏」

Session是服务器用来保存用户操作的一系列会话信息,由Web容器进行管理。单机情况下,不存在Session共享的情况,分布式情况下,如果不进行Session共享会出现请求落到不同机器要重复登录的情况,一般来说解决Session共享有以下几种方案。1、session复制session复制是早期的企业级的使用比较多的一种服务器集群session管理机制。应用服务器开启web容器的sessi…

大家好,又见面了,我是你们的朋友全栈君。

Session是服务器用来保存用户操作的一系列会话信息,由Web容器进行管理。单机情况下,不存在Session共享的情况,分布式情况下,如果不进行Session共享会出现请求落到不同机器要重复登录的情况,一般来说解决Session共享有以下几种方案。

1、session复制

session复制是早期的企业级的使用比较多的一种服务器集群session管理机制。应用服务器开启web容器的session复制功能,在集群中的几台服务器之间同步session对象,使得每台服务器上都保存所有的session信息,这样任何一台宕机都不会导致session的数据丢失,服务器使用session时,直接从本地获取。

这种方式在应用集群达到数千台的时候,就会出现瓶颈,每台都需要备份session,出现内存不够用的情况。

Terracotta实现Session复制

原理:Terracotta的基本原理是对于集群间共享的数据,在当一个节点发生变化的时候,Terracotta只把变化的部分发送给Terracotta服务器,然后由服务器把它转发给真正需要这个数据的节点。这种方案可以看成是对第二种方案的优化。

 

这里写图片描述

 

优点:这样对网络的压力非常小,各个节点也不必浪费CPU时间和内存进行大量的序列化操作。把这种集群间数据共享的机制应用在Session同步上,既避免了对数据库的依赖,又能达到负载均衡和灾难恢复的效果。

2、session绑定

利用hash算法,比如nginx的ip_hash,使得同一个Ip的请求分发到同一台服务器上。

这种方式不符合对系统的高可用要求,因为一旦某台服务器宕机,那么该机器上的session也就不复存在了,用户请求切换到其他机器后么有session,无法完成业务处理。

3、利用cookie记录session

session记录在客户端,每次请求服务器的时候,将session放在请求中发送给服务器,服务器处理完请求后再将修改后的session响应给客户端。这里的客户端就是cookie。

利用cookie记录session的也有缺点,比如受cookie大小的限制,能记录的信息有限;每次请求响应都需要传递cookie,影响性能,如果用户关闭cookie,访问就不正常。但是由于

cookie的简单易用,可用性高,支持应用服务器的线性伸缩,而大部分要记录的session信息比较小,因此事实上,许多网站或多或少的在使用cookie记录session。

4、session服务器

session服务器可以解决上面的所有的问题,利用独立部署的session服务器(集群)统一管理session,服务器每次读写session时,都访问session服务器。

这种解决方案事实上是应用服务器的状态分离,分为无状态的应用服务器和有状态的session服务器,然后针对这两种服务器的不同特性分别设计架构。

对于有状态的session服务器,一种比较简单的方法是利用分布式缓存(memcached), 数据库等。在这些产品的基础上进行包装,使其符合session的存储和访问要求。

如果业务场景对session管理有比较高的要求,比如利用session服务基层单点登录(sso),用户服务器等功能,需要开发专门的session服务管理平台。

分布式 session 在并发的情况下,会出现 session 不同步的问题?

可以使用 tair 的乐观锁解决这个问题,当用户取得 session 后,并获得一个版本号。当更 新 session 的时候,版本号+1。如果在跟新 session 的时候版本号不一致,则不能更新。保证 session 的一致性

使用Session共享,也分为两种机制,如下:

1、粘性Session处理方式

原理:不同的Tomcat指定访问不同的主memcached。多个memcached之间信息是同步的,能主从备份和高可用。用户访问时,首先在Tomcat中创建Session,然后将Session复制一份放到它对应的memcached上。memcached只起到备份左右,读写都在Tomcat上。当某一个Tomcat挂掉之后,集群将用户的访问定位到备Tomcat上,然后根据cookie中存储的SessionID找到Session,找不到时,再去相应的memcached上去寻找Session,找到之后将其复制到Tomcat上。

       这里写图片描述

2、非粘性Session处理方式

原理:memcached做主从复制,写入Session在从memcached服务器上,读取Session从主memcached,Tomcat本身不存储Session。

 

这里写图片描述

 

优点:可容错,Session实时响应。

实现方式:用开源的msm插件解决Tomcat之间的Session共享:Memcached_Session_Manager(MSM)

a. 复制相关jar包到tomcat/lib 目录下

JAVA memcached客户端:spymemcached.jar

msm项目相关的jar包:

1. 核心包,memcached-session-manager-{version}.jar
2. Tomcat版本对应的jar包:memcached-session-manager-tc{tomcat-version}-{version}.jar

序列化工具包:可选kryo,javolution,xstream等,不设置时使用jdk默认序列化。

b. 配置Context.xml ,加入处理Session的Manager

粘性模式配置: 

这里写图片描述

 

非粘性配置: 
这里写图片描述

 

3、微服务架构下分布式Session管理方案

经过上文的分析,在微服务架构中,使用Session集中管理的方式维护微应用的Session是比较好的选择。因为在Session存储介质上,Redis要比Memcache合适,所以使用Redis来集中存放微应用Session更为合适。在Session管理实现方案上,Spring Session的实现思路适用性较高,但是代码量大,学习和维护成本高,所以笔者认为参照Spring Session的思路,自己开发一套轻量级的代码是比较好的选择。

经过设计,微服务架构中的Session集中管理示意图如下。

分布式Session共享解决方案「建议收藏」

图5  Session集中管理方案示意图

1、参照SpringSession的实现,使用SessionFilter进行请求拦截,然后通过Request包装类接管Web服务器的Session管理。在Request包装类中,重写getSession方法,Session使用方法和过去一样,对使用者透明。

2、基于jedis开发一个分布式缓存SDK模块,用于Session共享模块和Redis中间进行通信,能够增加Session集中管理的可扩展性,如果需要支持其他的缓存服务器,对缓存SDK进行扩展开发即可。

3、搭建Redis集群用于存放微应用Session,以保证Session数据的高可用。Redis集群示意图如下。

分布式Session共享解决方案「建议收藏」

集群中包含两个Master和两个Slave,两个Master对Session数据进行分片存储,而Slave可用于进行数据备份和读写分离。

5、Session持久化到数据库

原理:拿一个数据库专门用来存储Session信息,保证Session的持久化。

优点:服务器出现问题,Session不会丢失。

缺点:如果网站的访问量很大,把Session存储到数据库中,会对数据库造成很大压力,还需要增加额外的开销,维护数据库。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/124770.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • php三个数从大到小排列_php常用的流程控制语句

    php三个数从大到小排列_php常用的流程控制语句<?php$a = rand(100,999);$b = rand(100,999);$c = rand(100,999);echo “a=”.”$a”.”<br>”;echo “b=”.”$b”.”<br>”;echo “c=”.”$c”.”<br>”;if(($a > $b ) && ($a > …

    2022年8月18日
    5
  • 二叉树性质及习题

    二叉树性质及习题二叉树性质:1.在二叉树的第k层至多有2^(k-1)个结点。(k>=1)2.深度为k的二叉树至多有2^(k-1)个结点(k>=1)。3.对任何一棵二叉树T,如果其叶结点数为n0,度为2的结点数为n2,则n0=n2+1。证明:若度为1的结点有n1个,总结点个数为n,总边数为e,则根据二叉树的定义,n=n0+n1+n2…

    2022年5月6日
    48
  • wifi reaver

    wifi reaverPIN码的格式很简单,八位十进制数,最后一位(第8位)为校验位(可根据前7位算出),验证时先检测前4位,如果一致则反馈一个信息,所以只需1万次就可完全扫描一遍前4位,前4位确定下来的话,只需再试1000次(接下来的3位),校验位可通过前7为算出,就可暴力验证出pin码。所以即时你不知道校验位怎么计算,那你最多尝试10000+1000+10次=11010次就可以获得PIN,从而获得wifi…

    2022年6月4日
    45
  • SSM-Spring(2)_AOP[通俗易懂]

    SSM-Spring(2)_AOP[通俗易懂]AOP用Spring需要导入包<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>方式一:使用Spring接口编写javapackage com.kuang.log;

    2022年8月8日
    3
  • Maven 菜鸟教程 5 常用插件配置

    Maven 菜鸟教程 5 常用插件配置jdk编译插件jetty插件把maven项目配置为标准web项目插件

    2022年9月7日
    0
  • C#开发之——ParameterizedThreadStart(14.4)「建议收藏」

    C#开发之——ParameterizedThreadStart(14.4)「建议收藏」一概述在C#语言中使用ParameterizedThreadStart创建进程,首先需要创建ParameterizedThreadStart委托的实例,然后再创建Thread类的实例<spanstyle=”color:#333333″>ParameterizedThreadStartpts=newParameterizedThreadStart(方法名);Threadt=newThread(pts);</span><!–more–>

    2022年7月15日
    16

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号