分布式Session框架。

在大型互联网系统中,单独使用Cookie和Session都是不可行的,原因很简单。因为如果使用Cookie,则可以很好的解决应用分布式部署问题,大型互联网应用系统的一个应用有上百台机器,而且有很多不同的应用系统协同工作,由于Cookie是将值存储在客户端的浏览器里,用户每次访问都会将最新的值带会给处理该请求的服务器,所以也就解决了同一个用户的请求可能不在同一台服务器处理而导致的Cookie不一致的问题。

存在哪些问题

这种“谁家的孩子谁抱走”的处理方式的确是大型互联网的一个比较简单,但的确可以解决问题的处理方式,但是这种处理方式也会带来了很多其他问题,如下所述。

  •     客户端Cookie存储限制。随着应用系统的增多,Cookie数量也快速增加,但浏览器对于用户Cookie的存储是有限制的。例如,对IE7之前的IE浏览器,Cookie个数的限制是20个;而对后续的版本,包括Firefox等,Cookie个数的限制都是50个,总大小不超过4KB,超过限制就会出现丢弃Cookie的现象,这会严重影响应用系统的正常使用。
  •     Cookie管理的混乱。在大型互联网应用系统中,如果每个应用系统都自己管理每个应用使用的Cookie,则会导致混乱,由于通常应用系统都在同一个域名下,Cookie又有上面一条提到的限制,所以没有统一管理很容易出现Cookie超出限制的情况。
  •     安全令人担忧。虽然可以通过设置HttpOnly属性防止一些私密Cookie被客户端访问,但是仍然不能保证Cookie无法被篡改。为了保证Cookie的私密性通常会对Cookie进行加密,但是维护这个加密Key也是一件麻烦的事情,无法保证定期更新加密Key也是带来安全性问题的一个重要因素。

当我们对以上问题不能再容忍下去时,就不得不想其他办法处理了。

可以解决哪些问题

既然Cookie有以上问题,Session也有他的好处,那么为何不结合使用Session和Cookie呢?下面是分布式Session框架可以解决的问题。

  •     Session配置的统一管理。
  •     Cookie使用的监控和统一规范管理。
  •     Session存储的多元化。
  •     Session配置的动态修改。
  •     Session加密key的定期修改。
  •     充分的容灾机制,保持框架的使用稳定性。
  •     Session各种存储的监控和报警支持。
  •     Session框架的可扩展性,兼容更多的Session机制如wapSession。
  •     跨域名Session与Cookie如何共享的问题。现在同一个网站可能存在多个域名,如何将Session和Cookie在不同的域名之间共享是一个具有挑战性的问题。

总体实现思路

分布式Session框架的架构图如下图所示。

为了达成上面所说的几个目标,我们需要一个服务订阅服务器,在应用启动时可以从这个订阅服务器订阅这个应用需要的可写Session项和可写Cookie项,这些配置的Session和Cookie可以限制这个应用能够使用哪些Session和Cookie,甚至可以控制Session和Cookie可读或者可写。这样可以精确的控制哪些应用可以操作哪些Session和Cookie,可以有效控制Session的安全性和Cookie的数量。

如Session的配置项可以为如下形式:

<session>
    <key>sessionID</key>
    <cookiekey>sessionID</cookiekey>
    <lifeCycle>9000</lifeCycle>
    <base64>true</base64>
</session>

Cookie的配置可以为如下形式:

<cookie>
    <key>cookie</key>
    <lifeCycle></lifeCycle>
    <type>1</type>
    <path>/wp</path>
    <domain>xxx.net</domain>
    <decrypt>false</decrypt>
    <httpOnly>false</httpOnly>
</cookie>

统一通过订阅服务器推送配置可以有效地集中管理资源,所以可以省去每个应用都来配置Cookie,简化Cookie的管理。如果应用要使用一个新增的Cookie,则可以通过一个统一的平台来申请,申请通过才将配置项增加到订阅服务器。如果是一个所有应用都要使用的全局Cookie,那么只需将这个Cookie通过订阅服务器统一推送过去就行了,省去了要在每个应用中手动增加Cookie的配置。

关于这个订阅服务器现在有很多开源的配置服务器,如Zookeeper集群管理服务器,可以统一管理所有服务器的配置文件。

由于应用是一个集群,所以不可能将创建的Session都保存在每台应用服务器的内存中,因为如果每台服务器有几十万的访问用户,那么服务器的内存肯定不够用,即使内存够用,这些Session也无法同步到这个应用的所有服务器中。所以要共享这些Session必须将他们存储在一个分布式缓存中,可以随时写入和读取,而且性能要很好才能满足要求。当前能满足这个要求的系统有很多,如MemCache或者淘宝的开源分布式缓存系统Tair都是很好的选择。

解决了配置和存储问题,下面看一下如何存取Session和Cookie。

既然是一个分布式Session的处理框架,必然会重新实现HttpSession的操作接口,使得应用操作Session的对象都是我们实现的InnerHttpSession对象,这个操作必须在进入应用之前完成,所以可以配置一个filter拦截用户的请求。

先看一下如何封装HttpSession对象和拦截请求,下图是时序图。

我们可以在应用的web.xml中配置一个SessionFilter,用于在请求到达MVC框架之前封装HttpServletRequest和HttpServletResponse对象,并创建我们自己的InnerHttpSession对象,把他设置到request和resposne对象中。这样应用系统通过request.getHttpSession()返回的就是我们创建的InnerHttpSession对象了,我们可以拦截response的addCookies设置的Cookie。

在时序图中,应用创建的所有Session对象都会保存在InnerHttpSession对象中,当用户的这次访问请求完成时,Session框架将会把这个InnerHttpSession的所有内容再更新到分布式缓存中,以便于这个用户通过其他服务器再次访问这个应用系统。另外,为了保证一些应用对Session稳定性的特殊要求,可以将一些非常关键的Session再存储到Cookie中,如当分布式缓存存在问题时,可以将部分Session存储到Cookie中,这样即使分布式缓存出现问题也不会影响关键业务的正常运行。

还有一个非常重要的问题就是如何处理跨域名来共享Cookie的问题。我们知道Cookie是有域名限制的,也就是在一个域名下的Cookie不能被另一个域名访问,所以如果在一个域名下已经登录成功,如何访问到另外一个域名的应用且保证登录状态仍然有效,对这个问题大型网站应该经常会遇到。如何解决这个问题呢?下面介绍一种处理方式,如下图所示。

从图中可以看出,要实现Session同步,需要另外一个跳转应用,这个应用可以被一个或者多个域名访问,他的主要功能是从一个域名下取得sessionID,然后将这个sessionID同步到另外一个域名下。这个sessionID其实就是一个Cookie,相当于我们经常遇到的JSESSIONID,所以要实现两个域名下的Session同步,必须要将一个sessionID作为Cookie写到两个域名下。

总共12步,一个域名不用登录就取到了另外一个域名下的Session,当然这中间有些步骤还可以简化,也可以做一些额外的工作,如可以写一些需要的Cookie,而不仅仅是传一个sessionID。

除此之外,该框架还能处理Cookie被盗取的问题。如你的密码没有丢失,但是你的账号却有可能被别人登录的情况,这种情况很可能就是因为你登录成功后,你的Cookie被别人盗取了,盗取你的Cookie的人将你的Cookie加入到他的浏览器,然后他就可以通过你的Cookie正常访问你的个人信息了,这是一个非常严重的问题。在这个框架中我们可以设置一个Session签名,当用户登录成功后我们根据用户的私密信息生成的一个签名,以表示当前这个唯一的合法登录状态,然后将这个签名作为一个Cookie在当前这个用户的浏览器进程中和服务器传递,用户每次访问服务器都会检查这个签名和从服务器分布式缓存中取得的Session重新生成的签名是否一致,如果不一致,则显然这个用户的登录状态不合法,服务端将清除这个sessionID在分布式缓存中的Session信息,让用户重新登录。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值