java session 管理器_通过 Spring Session 实现新一代的 Session 管理

本文探讨了传统JavaEE session管理在现代云环境中的问题,并介绍了Spring Session如何提供一种独立于应用服务器的session管理方案,支持可扩展的云应用、外部session存储、WebSocket session保持、非Web请求的session访问以及每个浏览器上的多session功能。Spring Session通过Servlet Filter实现,不依赖应用服务器特定API,易于配置和扩展,适用于各种数据存储,如Redis。
摘要由CSDN通过智能技术生成

长期以来,session 管理就是企业级 Java 中的一部分,以致于我们潜意识就认为它是已经解决的问题,在最近的记忆中,我们没有看到这个领域有很大的革新。

但是,现代的趋势是微服务以及可水平扩展的原生云应用(cloud native application),它们会挑战过去 20 多年来我们设计和构建 session 管理器时的前提假设,并且暴露了现代化 session 管理器的不足。

本文将会阐述最近发布的 Spring Session API 如何帮助我们克服眼下 session 管理方式中的一些不足,在企业级 Java 中,传统上都会采用这种旧的方式。我们首先会简单阐述一下当前 session 管理中的问题,然后深入介绍 Spring Session 是如何解决这些问题的。在文章的最后,将会详细展示 Spring Session 是如何运行的,以及在项目中怎样使用它。

Spring Session 为企业级 Java 应用的 session 管理带来了革新,使得以下的功能更加容易实现:

编写可水平扩展的原生云应用。

将 session 所保存的状态卸载到特定的外部 session 存储中,如 Redis 或 Apache Geode 中,它们能够以独立于应用服务器的方式提供高质量的集群。

当用户使用 WebSocket 发送请求的时候,能够保持 HttpSession 处于活跃状态。

在非 Web 请求的处理代码中,能够访问 session 数据,比如在 JMS 消息的处理代码中。

支持每个浏览器上使用多个 session,从而能够很容易地构建更加丰富的终端用户体验。

控制 session id 如何在客户端和服务器之间进行交换,这样的话就能很容易地编写 Restful API,因为它可以从 HTTP 头信息中获取 session id,而不必再依赖于 cookie。

需要说明的很重要的一点就是,Spring Session 的核心项目并不依赖于 Spring 框架,所以,我们甚至能够将其应用于不使用 Spring 框架的项目中。

传统 session 管理的问题

传统的 JavaEE session 管理会有各种问题,这恰好是 Spring Session 所要试图解决的。这些问题在下面以样例的形式进行了阐述。

构建可水平扩展的原生云应用

在原生的云应用架构中,会假设应用能够进行扩展,这是通过在 Linux 容器中运行更多的应用程序实例实现的,这些容器会位于一个大型的虚拟机池中。例如,我们可以很容易地将一个“.war”文件部署到位于 Cloud Foundry 或 Heroku 的 Tomcat 中,然后在几秒钟的时间内就能扩展到 100 个应用实例,每个实例可以具有 1GB RAM。我们还可以配置云平台,基于用户的需求自动增加和减少应用实例的数量。

在很多的应用服务器中,都会将 HTTP session 状态保存在 JVM 中,这个 JVM 与运行应用程序代码的 JVM 是同一个,因为这样易于实现,并且速度很快。当新的应用服务器实例加入或离开集群时,HTTP session 会基于现有的应用服务器实例进行重新平衡。在弹性的云环境中,我们会拥有上百个应用服务器实例,并且实例的数量可能在任意时刻增加或减少,这样的话,我们就会遇到一些问题:

重平衡 HTTP session 可能会成为性能瓶颈。

为了存储大量的 session,会需要很大的堆空间,这会导致垃圾收集,从而对性能产生负面影响。

云基础设施通常会禁止 TCP 多播(multicast),但是 session 管理器常常会使用这种机制来发现哪一个应用服务器实例加入或离开了集群。

因此,更为高效的办法是将 HTTP session 状态保存在独立的数据存储中,这个存储位于运行应用程序代码的 JVM 之外。例如,我们可以将 100 个 Tomcat 实例配置为使用 Redis 来存储 session 状态,当 Tomcat 实例增加或减少的时候,Redis 中所存储的 session 并不会受到影响。同时,因为 Redis 是使用 C 语言编写的,所以它可以使用上百 GB 甚至 TB 级别的 RAM,它不会涉及到垃圾收集的问题。

对于像 Tomcat 这样的开源服务器,很容易找到 session 管理器的替代方案,这些替代方案可以使用外部的数据存储,如 Redis 或 Memcached。但是,这些配置过程可能会比较复杂,而且每种应用服务器都有所差别。对于闭源的产品,如 WebSphere 和 Weblogic,寻找它们的 session 管理器替代方案不仅非常困难,在有些时候,甚至是无法实现的。

Spring Session 提供了一种独立于应用服务器的方案,这种方案能够在 Servlet 规范之内配置可插拔的 session 数据存储,不依赖于任何应用服务器的特定 API。这就意味着 Spring Session 能够用于实现了 servlet 规范的所有应用服务器之中(Tomcat、Jetty、 WebSphere、WebLogic、JBoss 等),它能够非常便利地在所有应用服务器中以完全相同的方式进行配置。我们还可以选择任意最适应需求的外部 session 数据存储。这使得 Spring Session 成为一个很理想的迁移工具,帮助我们将传统的 JavaEE 应用转移到云中,使其成为满足  12-factor 的应用。

每个用户有多个账号

假设我们在 example.com 上运行面向公众的 Web 应用,在这个应用中有些用户会创建多个账号。例如,用户 Jeff Lebowski 可能会有两个账户 thedude@example.com 和 lebowski@example.com。和其他 Java Web 应用一样,我们会使用HttpSession来跟踪应用的状态,如当前登录的用户。所以,当用户希望从 thedude@example.com 切换到 lebowski@example.com 时,他必须要首先退出,然后再重新登录回来。

借助 Spring Session,为每个用户配置多个 HTTP session 会非常容易,这样用户在 thedude@example.com 和 lebowski@example.com 之间切换的时候,就不需要退出和重新登录了。

多级别的安全预览

假设我们正在构建的 Web 应用有一个复杂、自定义的权限功能,其中应用的 UI 会基于用户所授予的角色和权限实现自适应。

例如,假设应用有四个安全级别:public、confidential、secret 和 top secret。当用户登录应用之后,系统会判断用户所具有的最高安全级别并且只会显示该级别和该级别之下的数据。所以,具有 public 权限的用户只能看到 public 级别的文档,具有 secret 权限的用户能够看到 public、confidential 和 secret 级别的文档,诸如此类。为了保证用户界面更加友好,应用程序应该允许用户预览在较低的安全级别条件下页面是什么样子的。例如,top secret 权限的用户能够将应用从 top secret 模式切换到 secret 模式,这样就能站在具有 secret 权限用户的视角上,查看应用是什么样子的。

典型的 Web 应用会将当前用户的标识及其角色保存在 HTTP session 中,但因为在 Web 应用中,每个登录的用户只能有一个 session࿰

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值