独立实现一个分布式session

对于一个独立应用来说,单机部署不需要考虑分布式问题,默认的session实现就行了,一旦多机部署,首先我们需要修改session方案,分布式session解决的是多机session状态同步的问题,一般情况下,会有2种常见的方案

1,简单点,机器间相互同步,当一台机器上的session状态改变后,自动发送请求到其他所有机器上,同步状态,这样做当然是可行的,但缺点也很明显,机器之间的网络通讯比较频繁,而且网络问题会引起某些机器的session状态未及时同步,导致用户端访问出现异常

2,对于多机部署的应用来说,用一台机器做session服务器,应用集群全部请求这台session服务器获取session信息,这样做避免了状态同步这种繁琐的事情,但仍有缺点,当qps很高的情况下,session服务器的网络压力会非常大,因为所有请求都会落到这一台机器上来,一般存储session信息可以使用redis或者其他分布式cache数据库来做,如何解决上述问题呢,我的做法是,充分利用每台应用服务器的内存做一个二级缓存,来缓解session服务器的压力,只有session信息改变后application才会去请求session 服务器拉去最新的session信息同步到本机,否则直接读取本机session返回给客户端,那如何做呢,大家都知道,浏览器是根据sessionid这个标识传给服务器读取session的,我们提出一个跟sessionid同等地位概念,叫版本:session_version,我们将session_version存储到cookie中,且在服务端也存储起来,可以跟sessionid做一个一对一的关联;ok,当用户发起请求到服务器改变了session信息后,该服务器读取cookie中的session_version,对其加一后更新cookie;这时候用户cookie里的session_version已经改变,用户再起请求服务器,可能请求落到其他机器上,那这台机器先检查本服务器上的sessionid对应的session_version版本是否比用户cookie中的低,如果低,则请求session服务器获取最新的session,同时更新服务器内存中的session_version到最新版本,如果session_version比对一致,则直接返回服务器本地的session给用户;

这样做可以充分环节session服务器的压力,但对应用server的内存要求就会有些高了,因为要缓存session信息,我推荐应用使用本地缓存存储session信息,例如ehcache这种的,信息可以同步到硬盘上持久化一下;这个方案适合一些中型业务规模的应用,并不适合超大规模业务场景;

3,其实我们还有别的方案,就是session服务器可以做成集群,这样就不会出现所有请求都落到一台session服务器上去,那这时候就会有新的问题了,既然是集群,那么对于session集群来说,server的数量会有增有减,我们应用获取session信息往往是通过:sessionService.getSession(sessionid);这样的方式去获取的,这很像hash的做法,效率高,键值对;那既然是session集群,必然存在当我根据sessionid求hash时,怎么确定落在哪台具体的session服务器上呢,如果求hash的过程是在client端进行,那就太不灵活了,一旦机器有增减,就会导致你get不到数据,所以这个集群需要做个代理服务,由这个服务统一想client提供服务,然后代理服务里面做这个hash映射的事情;ok,这时候,我要增加一台机器,那之前hash的那些映射关系必然会被打乱,撤掉一台机器,也一样会出问题,我们怎么解决这样的问题呢,答案是一致性hash,组成一个环状结构,每个hash落点存储到离他最近的那台机器上去,增删数据时,当我们下掉机器后,要把本机器上的数据,重新hash迁移一下,增加机器时,将落到本机上的数据从其他机器上迁移过来,这种叫集群内部的自动化调整,这样就保证了数据的一致性,我们也方便进行扩容和下线;

另外还有一个问题,对于一些应用来说,可能某一部分用户的活跃度很高,导致在这个环形的hash分布中,hash落点出现聚集效应,结果就是个别机器的存储量明显高于其他机器,这样资源利用和负载明显不均衡,如何解决这个问题呢,答案是,我们可以再做一次虚拟映射,将每天机器上映射成多个节点,平均地分布到环形区域中,这样hash落点只是落到虚拟节点上,从而完美滴解决了hash分布不均衡的问题,当然由于再次封装了一层,这会导致性能上的损失,但这种损失是微乎其微的,可以接受。

时间: 2024-10-19 03:53:12

独立实现一个分布式session的相关文章

基于ZooKeeper的分布式Session实现(转)

1.   认识ZooKeeper ZooKeeper—— “动物园管理员”.动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被动 物所观赏.为了让各种不同的动物呆在它们应该呆的地方,而不是相互串门,或是相互厮杀,就需要动物园管理员按照动物的各种习性加以分类和管理,这样我们才 能更加放心安全的观赏动物.回到我们企业级应用系统中,随着信息化水平的不断提高,我们的企业级系统变得越来越庞大臃肿,性能急剧下降,客户抱怨频频.拆 分系

基于ZooKeeper的分布式Session实现

基于ZooKeeper的分布式Session实现 1.   认识ZooKeeper ZooKeeper—— “动物园管理员”.动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被动 物所观赏.为了让各种不同的动物呆在它们应该呆的地方,而不是相互串门,或是相互厮杀,就需要动物园管理员按照动物的各种习性加以分类和管理,这样我们才 能更加放心安全的观赏动物.回到我们企业级应用系统中,随着信息化水平的不断提高,我们的企业级系统变得越

Java Web学习总结(20)——基于ZooKeeper的分布式session实现

1.   认识ZooKeeper ZooKeeper-- "动物园管理员".动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被动 物所观赏.为了让各种不同的动物呆在它们应该呆的地方,而不是相互串门,或是相互厮杀,就需要动物园管理员按照动物的各种习性加以分类和管理,这样我们才 能更加放心安全的观赏动物.回到我们企业级应用系统中,随着信息化水平的不断提高,我们的企业级系统变得越来越庞大臃肿,性能急剧下降,客户抱怨频频

net之session漫谈及分布式session解决方案

最近一直在纠结net下分布式会话的实现,现将近日来的个人感想记录如下,如果有什么更好的解决方案请指教. 1.什么是session: Session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去.当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象.当会话过期或被放弃后,服务器将终止该会话.Session 对象

Spring Session解决分布式Session问题的实现原理

使用Spring Session和Redis解决分布式Session跨域共享问题 上一篇介绍了如何使用spring Session和Redis解决分布式Session跨域共享问题,介绍了一个简单的案例,下边就学习一下Spring Session的实现原理. 注:以下步骤是基于XML的方式实现 Spring Session的代码讲解! 先从web.xml文件说起 我们知道Tomcat再启动的时候首先会去加载web.xml 文件,Tomcat启动的时候web.xml被加载的顺序:context-pa

HttpServletRequestWrapper模拟实现分布式Session

HttpSession的内容都放在一个单独的Map中,模拟远程分布式Session. 1.使用HttpServletRequestWrapper创建自定义Request2.使用动态代理包装自定义Request返回的HttpSession对象3.创建过滤器,使用自定义Request替换原有的Request对象.4.在Servlet中得到的HttpSession对象,写入和读取内容都假设通过远程Session服务器. 创建自定义的Request,返回动态代理的HttpSession import j

[Node.js] Node + Redis 实现分布式Session方案

Session是什么? Session 是面向连接的状态信息,是对 Http 无状态协议的补充. Session 怎么工作? Session 数据保留在服务端,而为了标识具体 Session 信息指向哪个连接,需要客户端传递向服务端发送一个连接标识,比如存在Cookies 中的session_id值(也可以通过URL的QueryString传递),服务端根据这个id 进行存取状态信息. 在服务端存储 Session,可以有很多种方案: 内存存储 数据库存储 分布式缓存存储 分布式Session

如何使用Spring Session实现分布式Session管理

Spring Session作为Spring社区官方推荐的一个比较简单快速的Java Web分布式session解决方案,帮我们搞定了长期以来比较蛋疼的session分布式的问题. Spring Session解决的基本思路很简单,即将用户的session信息全部存放到一个redis数据库中,所有的session都从这个数据库拿.由于redis是一个内存数据库,数据信息读写是非常快速的.如此一来,多个Tomcat,共用一个redis数据库,即实现了session的共享问题. 鉴于目前很少看到Sp

分布式session实现方式

当一个传统的Web项目需要从单点扩张成为集群式时候,需要考虑的一个问题:分布式Session的实现.通常分布式session有三种解决方式,现对三种方式进行简单记录: 1.session广播 顾名思义,广播就是在集群里的所有服务器将他们的session向其他服务器进行同步,使得每一台服务器上都有其他服务器的session信息,这样,不管请求进入那个服务器,都可以获取session信息.这种方式从理解和实现方面都比较简单,同时避免了单点故障引起的session丢失问题.但是因为广播是多台服务器同步