解决session共享问题方式调研

为了提高服务器性能,最近公司项目采用了分布式服务集群的部署方式。所谓集群,就是让一组计算机服务器协同工作,解决大并发,大数据量瓶颈问题。项目使用nginx做负载均衡,这样同一个IP访问同一个页面会被分配到不同的服务器上,此时就涉及到一个session共享的问题。因为session是在服务器端保存的,如果用户跳转到其他服务器的话,session就会丢失,一般情况下,session不可跨服务器而存在。于是就有了分布式系统的session共享问题。

集群中session安全和同步是个最大的问题,下面是收集到的几种session同步的方案,希望能通过分析其各自的优劣找出其适应的场景。

一、客户端cookie加密

当用户登陆成功以后,把网站域名、用户名、密码、token、 session有效时间全部采用cookie的形式写入到客户端的cookie里面。如果用户从一台Web服务器跨越到另一台服务器的时候,我们的程序主动去检测客户端的cookie信息,进行判断,然后提供对应的服务,当然,如果cookie过期,或者无效,自然就不让用户继续服务了。

优点:

简单、高效,也不会加大数据库的负担。

缺点:
  1. cookie安全性较低,虽然它已经加了密,但是还是可以伪造的。
  2. 但是如果客户端把cookie禁掉了的话,那么session就无从同步了,这样会给网站带来损失;
  3. session中数据不能太多,最好只有个用户id。

二、session复制

大部分应用服务器都提供了session复制的功能来实现集群,tomcat,jboss,was都提供了这样的功能。

优点:

通过应用服务器配置即可,无需改动代码。

缺点:
  1. 性能随着服务器增加急剧下降,而且容易引起广播风暴;
  2. session数据需要序列化,影响性能。

三、使用数据库保存session

这种共享session的方式即将session信息存入数据库中,其它应用可以从数据库中查出session信息。

优点:

使用数据库来保存session,就算服务器宕机了也没事,session照样在。

缺点:
  1. 每次请求都需要对数据库进行读写,session的并发读写在数据库中完成,会加大数据库的IO,对数据库性能要求比较高。
  2. 我们需要额外地实现session淘汰逻辑代码,即定时从数据库表中更新和删除session信息,增加了工作量。
  3. 数据库读写速度较慢,不利于session的适时同步。

四、使用redis或memcache来保存session

提供一个集群保存session共享信息,其他应用统统把自己的session信息存放到session集群服务器组。当应用系统需要session信息的时候直接到session群集服务器上读取。目前大多都是使用Memcache或redis来对Session进行存储。以这种方式来同步session,不会加大数据库的负担,并且安全性比用cookie大大的提高,把session放到内存里面,比从文件中读取要快很多。
以redis来实现Session共享的方式目前比较流行的有两种实现方案,下面主要对这两种方案进行介绍。

1. tomcat-cluster-redis-session-manager

使用 tomcat-redis-session-manager 开源项目解决分布式session跨域的问题,他的主要思想是利用Servlet容器提供的插件功能,自定义HttpSession的创建和管理策略,并通过配置的方式替换掉默认的策略。tomcat-redis-session-manager重写了Tomcat的org.apache.catalina.session.ManagerBase里边的具体写的操作, 将tomcat的session存储位置指向了Redis:

RedisSessionManager 继承了org.apache.catalina.session.ManagerBase并重写了 addfindSessioncreateEmptySessionremove 等方法,并将对session 的增删改查操作指向了对Redis数据存储的操作。

具体可以参考:Redis+Tomcat+Nginx集群实现Session共享,Tomcat Session共享

优点:

无需修改任何代码。

缺点:
  1. 配置相对还是有一点繁琐,需要人为的去修改Tomcat的配置。
  2. 暂时此插件只支持tomcat7、tomcat8、tomcat9,对于tomcat有较大的依赖。

2. 使用Spring Session和redis管理session

Spring Session不依赖于Servlet容器,而是Web应用代码层面的实现,直接在已有项目基础上加入spring Session框架来实现Session统一存储在Redis中。如果你的Web应用是基于Spring框架开发的,只需要对现有项目进行少量配置,即可将一个单机版的Web应用改为一个分布式应用,由于不基于Servlet容器,所以可以随意将项目移植到其他容器。

优点:
  1. 如果web应用是基于spring框架开发的,那么只需简单配置,既可以修改为一个分布式应用。
  2. 不急于servlet容器,可以随意将项目移植到其他容器。
缺点:

需要修改代码。

具体可以参考:使用Spring Session和Redis解决分布式Session跨域共享问题


参考链接:

解决nginx负载均衡的session共享问题

java集群之session共享解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值