RedisHttpSession 的设计与实现

前言

RedisHttpSession 是我的一个 Java 开源项目,通过将 Session 存储在 Redis 中实现多服务器间共享 Session,同时这一过程是完全透明的。主要用于支持 RESTfuls API。下面我将对其核心类进行分析,阐述它的设计以及实现细节。

RedisHttpSession

这个类实现了HttpSession接口,用于替换默认的HttpSession实现。RedisHttpSessionHttpSession的接口方法重写了一遍,将HttpSession的属性存储到了 Redis 中。

每个RedisHttpSession都有一个 UUID 与之对应,该字段加上session:前缀作为存储在 Redis 中的键值。例如:

同时,RedisHttpSession中的属性是直接序列化成字节数组存储在 Redis 中的,存储在对应键中的哈希表里面。例如:

另外,Session 的自动过期是通过 Redis 设置键的过期时间实现的。

RedisHttpSessionProxy

RedisHttpSessionProxyRedisHttpSession的代理类,使用了 JDK 的动态代理。为什么要引入代理?这是基于下面的考虑做出的设计。

  1. 由于 Session 存储在 Redis 中,在执行每个RedisHttpSession的接口方法之前都需要检查 Redis 连接是否可用。
  2. 访问一个已经被注销的 Session 需要抛出异常。
  3. 每次访问 Session 需要刷新过期时间和最后访问时间。

基于上面的考虑,对于每个RedisHttpSession的接口方法,我们都需要进行重复的操作,因此使用动态代理对每个接口方法进行增强是最合适的。代码如下:

RedisHttpSessionFilter

RedisHttpSessionFilter作为过滤器,将请求和响应替换成RedisSessionRequestWrapperRedisSessionResponseWrapper,利用了装饰器模式动态的给请求和响应进行增强:

  1. RedisSessionRequestWrapper:重写了getSession,替换默认的HttpSession实现为RedisHttpSession
  2. RedisSessionResponseWrapper:在响应的头部中加入x-auth-token字段,作为 Session 的 ID。客户端之后的请求都需要附带该字段,以便服务端识别对应的 Session。

总结

RedisHttpSession 利用 Filter 将请求的 Session 替换成 RedisHttpSession,在过滤阶段偷梁换柱,在之后对 Session 的操作都无需关心其内部实现,整个过程都是透明的。

打赏支持我写出更多好文章,谢谢!

打赏作者

打赏支持我写出更多好文章,谢谢!

任选一种支付方式

1 3 收藏 评论

关于作者:肖汉松

热爱阅读,喜欢挑战。热衷尝试新的技术,关注技术背后的原理。关注领域:Java 服务端开发,网络编程。关注语言:Java, C, Python。 个人主页 · 我的文章 · 39 ·    

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部