Spring Session DefaultCookieSerializer.setJvmRoute 有效,但 HttpServletRequest 没有所需的 jvmRoute

SpringSession DefaultCookieSerializer.setJvmRoute works, but HttpServletRequest does not have the jvmRoute required

我已经在我的遗留 Spring MVC 应用程序中使用 Redis 实现了 Spring 会话。我还使用 DefaultCookieSerializer 来设置 jvmRoute,因为我需要 Talend 作业的一些服务器亲和力才能 运行.

当我 运行 前端检查 Chrome 中的页面时,我看到附加到会话的 jvmRoute。如果我将其从 "node1" 编辑为 "node2",会话将被保留。如果我重新部署服务器并在该部署期间发出请求,我将被重定向到集群中的另一个节点,这意味着 Spring 会话工作正常。

但是,我无法获得服务器关联,因为当我调试 HttpServletRequest 进入我的 Spring 应用程序时,HttpServletRequest.getSession().getId() 没有 jvmRoute在其中(尽管十六进制数与我在 Chrome 中看到的相符),这就是我传递给 Talend 作业的内容。

如果我恢复到 Tomcat 会话并在 server.xml 的引擎组件中设置 jvmRoute,我会看到 jvmRoute 附加到会话 ID Chrome 和调试代码时。

DefaultCookieSerializer 的具体作用是什么?我认为它会在创建 cookie 时对其进行编辑,这就是 cookie 存储在 Redis 中的方式。因此,如果您以这种方式设置,则在创建此 cookie 之后对其进行的任何使用都应附加 jmvRoute

What exactly does the DefaultCookieSerializer do? I thought it edits the cookie as it is being created, and that is how the cookie is to be stored in Redis. So any use of this cookie subsequent to being created should have the jmvRoute attached if you set it up that way.

首先,重要的是要意识到 cookie 本身并未存储在 session 存储中(即在您的情况下为 Redis)。存储的是 session 本身的表示及其属性。

除了session 存储,session 管理的另一个重要方面是用户的HTTP 请求与存储session 的关联。对于 Spring Session 的 Servlet API 支持,这是 HttpSessionIdResolver 的责任,默认情况下 Spring Session 使用基于 cookie 的实现,即 CookieHttpSessionIdResolver。在 HeaderHttpSessionIdResolver 中还有一个基于 HTTP header 的实现。我这样说是因为重要的是要认识到 session 存储是在不同级别上运行的不同问题。

现在,关于 CookieHttpSessionIdResolver,它将 cookie 写入和读取问题委托给 CookieSerializerDefaultCookieSerializer 是……好吧,默认实现)。根据其配置,DefaultCookieSerializer 在写入和读取 session cookie 时会考虑一些选项,即 cookie 名称、是否对 cookie 值进行 Base64 编码、是否使用 httpOnly cookie 指令等。

However, I cannot get server affinity because when I debug a HttpServletRequest as it comes into my Spring app, the HttpServletRequest.getSession().getId() doesn't have the jvmRoute in it (although the hex number matches what I see in Chrome), and this is what I pass to the Talend job.

这是我不明白的部分 - 如果您能够从当前的 HttpServletRequest 中解析出 HttpSession 那么您就知道 jvmRoute 是什么了吧?它是当前 JVM 的 jvmRoute,否则 session 不会被此 JVM 处理 HttpServletRequest 解析。

Spring Session 和 Tomcat 的 session 管理之间的不同之处在于 Tomcat jvmRoutesession id generation related concern 而 Spring Session jvmRoute 在 session cookie 序列化的上下文中使用。