session共享怎么做的(分布式如何实现session共享)? 
问题描述:一个用户在登录成功以后会把用户信息存储在session当中,这时session所在服务器为server1,那
么用户在 session 失效之前如果再次使用 app,那么可能会被路由到 server2,这时问题来了,server 没有该用户的
session,所以需要用户重新登录,这时的用户体验会非常不好,所以我们想如何实现多台 server 之间共享 session,
让用户状态得以保存。 
1、服务器实现的session复制或session共享,这类型的共享session是和服务器紧密相关的,比如webSphere
或JBOSS在搭建集群时候可以配置实现session复制或session共享,但是这种方式有一个致命的缺点,就是不好扩
展和移植,比如我们更换服务器,那么就要修改服务器配置。 
2、利用成熟的技术做session复制,比如12306使用的gemfire,比如常见的内存数据库如redis或memorycache,
这类方案虽然比较普适,但是严重依赖于第三方,这样当第三方服务器出现问题的时候,那么将是应用的灾难。 
3、将 session维护在客户端,很容易想到就是利用cookie,但是客户端存在风险,数据不安全,而且可以存放的
数据量比较小,所以将session维护在客户端还要对session中的信息加密。 
我们实现的方案可以说是第二种方案和第三种方案的合体,可以利用 gemfire 实现 session 复制共享,还可以将
session维护在redis中实现session共享,同时可以将session维护在客户端的cookie中,但是前提是数据要加密。
这三种方式可以迅速切换,而不影响应用正常执行。我们在实践中,首选 gemfire 或者 redis 作为 session 共享的载
体,一旦session不稳定出现问题的时候,可以紧急切换cookie维护session作为备用,不影响应用提供服务。 
这里主要讲解 redis 和 cookie 方案,gemfire 比较复杂大家可以自行查看 gemfire 工作原理。利用 redis 做
session共享,首先需要与业务逻辑代码解耦,不然session共享将没有意义,其次支持动态切换到客户端cookie模
式。redis的方案是,重写服务器中的HttpSession和HttpServletRequest,首先实现HttpSession接口,重写session
的所有方法,将session以hash值的方式存在redis中,一个session的key就是sessionID,setAtrribute重写之
后就是更新 redis 中的数据,getAttribute 重写之后就是获取 redis 中的数据,等等需要将 HttpSession 的接口一一
实现。 
实现了HttpSesson,那么我们先将该session类叫做MySession(当然实践中不是这么命名的),当MySession
出现之后问题才开始,怎么能在不影响业务逻辑代码的情况下,还能让原本的 request.getSession()获取到的是
MySession,而不是服务器原生的session。这里,我决定重写服务器的HttpServletRequet,这里先称为MyRequest,
但是这可不是单纯的重写,我需要在原生的request基础上重写,于是我决定在filter中,实现request的偷梁换柱,
我的思路是这样的,MyRequest的构建器,必须以request作为参数,于是我在filter中将服务器原生的request(也
有可能是框架封装过的 request),当做参数 new 出来一个 MyRequest,并且 MyRequest 也实现了
HttpServletRequest接口,其实就是对原生request的一个增强,这里主要重写了几个request的方法,但是最重要
的是重写了request.getSession(),写到这里大家应该都明白为什么重写这个方法了吧,当然是为了获取MySession,
于是这样就在filter中,偷偷的将原生的request换成MyRequest了,然后再将替换过的request传入chan.doFilter(),
这样 filter 时候的代码都使用的是 MyRequest 了,同时对业务代码是透明的,业务代码获取 session 的方法仍然是
request.getSession(),但其实获取到的已经是MySession了,这样对session的操作已经变成了对redis的操作。
这样实现的好处有两个,第一开发人员不需要对session共享做任何关注,session共享对用户是透明的;第二,filter
是可配置的,通过filter的方式可以将session共享做成一项可插拔的功能,没有任何侵入性。 
这个时候已经实现了一套可插拔的session共享的框架了,但是我们想到如果redis服务出了问题,这时我们该怎
么办呢,于是我们延续redis 的想法,想到可以将 session 维护在客户端内(加密的 cookie),当然实现方法还是一
样的,我们重写 HttpSession 接口,实现其所有方法,比如 setAttribute 就是写入 cookie,getAttribute 就是读取
cookie,我们可以将重写的session 称作 MySession2,这时怎么让开发人员透明的获取到 MySession2呢,实现方
法还是在filter内偷梁换柱,在MyRequest加一个判断,读取sessionType配置,如果sessionType是redis的,那
么getSession的时候获取到的是MySession,如果sessionType是coolie的,那么getSession的时候获取到的是
MySession2,以此类推,用同样的方法就可以获取到MySession 3,4,5,6等等。 
这样两种方式都有了,那么我们怎实现两种 session 共享方式的快速切换呢,刚刚我提到一个 sessionType,这
是用来决定获取到session的类型的,只要变换sessionType就能实现两种session共享方式的切换,但是sessionType
必须对所有的服务器都是一致的,如果不一致那将会出现比较严重的问题,我们目前是将 sessionType 维护在环境变
量里,如果要切换 sessionType就要重启每一台服务器,完成 session共享的转换,但是当服务器太多的时候将是一
种灾难。而且重启服务意味着服务的中断,所以这样的方式只适合服务器规模比较小,而且用户量比较少的情况,当服
务器太多的时候,务必需要一种协调技术,能够让服务器能够及时获取切换的通知。基于这样的原因,我们选用
zookeeper 作为配置平台,每一台服务器都会订阅 zookeeper 上的配置,当我们切换 sessionType 之后,所有服务
器都会订阅到修改之后的配置,那么切换就会立即生效,当然可能会有短暂的时间延迟,但这是可以接受的。

文章来自www.wityx.com,转载请注明出处!原文地址http://www.wityx.com/post/1321_1_1.html

session共享怎么做的(分布式如何实现session共享)?相关推荐

  1. Session机制详解及分布式中Session共享解决方案

    Session机制详解及分布式中Session共享解决方案 参考文章: (1)Session机制详解及分布式中Session共享解决方案 (2)https://www.cnblogs.com/jing ...

  2. 【微服务之分布式Session】Session机制详解及分布式中Session共享解决方案

    一.为什么要产生Session http协议本身是无状态的,客户端只需要向服务器请求下载内容,客户端和服务器都不记录彼此的历史信息,每一次请求都是独立的. 为什么是无状态的呢?因为浏览器与服务器是使用 ...

  3. php session域名共享,实现多域名下共用一个SESSION

    要实现多域名共享session,首先就得了解SESSION的运行机制.基本概念我就不说了. session是这样运行的: 用户A访问站点Y,如果站点Y执行了session_start();(以下假定s ...

  4. 分布式下的session问题

    分布式下的session 在分布式项目下 项目中使用 在分布式项目下 session是一种会话状态,是储存在服务器上的,可以区分每个用户.浏览器会保存着对应的信息.浏览器保存的叫cookie.用户访问 ...

  5. 分布式部署时Session可能存在的问题

    目录 分布式部署时Session可能存在的问题 1)问题 2)解决办法 ①:粘性Session ②:同步Session ③:共享Session ④:数据库Session(主流做法) ⑤:数据库Sess ...

  6. redis/分布式文件存储系统/数据库 存储session,解决负载均衡集群中session不一致问题...

    先来说下session和cookie的异同 session和cookie不仅仅是一个存放在服务器端,一个存放在客户端那么笼统 session虽然存放在服务器端,但是也需要和客户端相互匹配,试想一个浏览 ...

  7. 分布式调度架构:共享状态调度

    分布式调度架构:共享状态调度 前言 什么是共享状态调度? 共享状态调度设计 Omega 调度架构 Omega 共享调度工作原理 知识扩展:单体调度.两层调度和共享调度的区别是什么? 总结 前言 在两层 ...

  8. 【部署】SpringBoot 打包部署/共享依赖包(分布式开发集中式部署微服务)精简jar包

    精简jar包 将项目跟第三方依赖分开 [部署]SpringBoot 打包部署/共享依赖包(分布式开发集中式部署微服务) 1 修改pom <build><plugins>< ...

  9. cookie session token区别_彻底理解cookie,session,token

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 作者: 墨颜丶 cnblogs.com/moyand/p/9047978.html 发展史 ...

最新文章

  1. 为图片添加半透明遮罩效果
  2. 有一台电脑怎么挣钱_大聪明,双十一我想6000元配置一台能畅玩主流游戏的电脑,应该怎么搭配?...
  3. struts struts.xml
  4. 新概念 Lesson 7 A new dress 定冠词、不定冠词
  5. easyui是否容易上手_特色家常菜-清蒸桂鱼,肉质鲜嫩有营养,做法简单容易学...
  6. 关于 Angular 项目类型为 library 的工程使用 tsconfig.json 的问题
  7. C#任务调度——LimitedConcurrencyLevelTaskScheduler
  8. 去除字符串最后一位的几种方法
  9. HTML min/maxlength
  10. 一道经典面试题的不同解法
  11. 每天一个linux命令
  12. Can‘t exec “autopoint“: 没有那个文件或目录 at /usr/share/autoconf/Autom4te/FileUtils.pm line 345.
  13. 杨校老师课堂之Hadoop环境搭建(一)
  14. php 应用截图,PHP实现网页截图?
  15. Unity 武器拖尾效果
  16. java.sql.SQLException: Access denied for user '''localhost' (using password: NO) 的处理方法
  17. 水泊梁山好汉们的排名技巧
  18. 前端js实现表格数据的上移下移
  19. 最长公共子序列(LCS)算法
  20. 第9周测验-鸣人和佐助

热门文章

  1. 【机器学习基础】对样本不均衡的处理
  2. (GitHub标星6.9k)超详细的人工智能专家路线图,
  3. 【NLP】打破BERT天花板:11种花式炼丹术刷爆NLP分类SOTA!
  4. 【机器学习基础】数学推导+纯Python实现机器学习算法13:Lasso回归
  5. 最简单的opencv安装方法----利用annaconda安装opencv
  6. LeetCode_559.N叉树的最大深度
  7. 如何为Apache Kylin快速开发新数据源?
  8. NLPIR智能语义技术从采集到分析一步到位
  9. 《数据挖掘与数据化运营实战 思路、方法、技巧与应用》—— 读书笔记
  10. python之4个小作业