问题描述
我已经在我的旧 Spring MVC 应用程序中使用 Redis
实现了 Spring Session.我还使用了 DefaultCookieSerializer
来设置 jvmRoute
,因为我需要一些服务器关联才能运行 Talend 作业.
I have implemented Spring Session with Redis
in my legacy Spring MVC application. I also used the DefaultCookieSerializer
to set the jvmRoute
, because I need some server affinity for Talend jobs to be able to run.
当我运行前端并在 Chrome 中检查页面时,我看到 jvmRoute
附加到会话中.如果我将其从node1"编辑为node2",会话将被保留.如果我重新部署服务器并在部署期间发出请求,我会被重定向到集群中的另一个节点,这意味着 Spring Sessions 运行良好.
When I run the front end and inspect the page in Chrome, I see the jvmRoute
appended to the session. If I edit this from "node1" to "node2", the session is preserved. If I redeploy the server and make requests during that deployment, I get redirected to another node in the cluster, which means that Spring Sessions is working perfect.
但是,我无法获得服务器关联,因为当我调试 HttpServletRequest
进入我的 Spring 应用程序时,HttpServletRequest.getSession().getId()
没有t 中有 jvmRoute
(尽管十六进制数与我在 Chrome 中看到的相匹配),这就是我传递给 Talend 作业的内容.
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.
如果我恢复到 Tomcat 会话并在 server.xml
的引擎组件中设置 jvmRoute
,我会看到 jvmRoute
附加到Chrome 中和调试代码时的会话 ID.
If I revert back to Tomcat session and set the jvmRoute
in the Engine component of server.xml
, I see the jvmRoute
appended to the session id in both Chrome and when debugging the code.
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 本身并不存储在会话存储中(即在您的情况下是 Redis).存储的是会话本身及其属性的表示.
First, it's important to realize the cookie itself isn't stored in session store (i.e. Redis in your case). What's stored is the representation of session itself, along with its attributes.
除了会话存储之外,会话管理的另一个重要方面是用户的 HTTP 请求与存储的会话的关联.有了 Spring Session 的 Servlet API 支持,这是 HttpSessionIdResolver
的责任,默认情况下 Spring Session 使用基于 cookie 的实现,即 CookieHttpSessionIdResolver
.HeaderHttpSessionIdResolver
中还有一个基于 HTTP 标头的实现.我之所以这么说是因为重要的是要意识到会话存储是在不同级别上运行的不同关注点.
Besides session storage, other important aspect of session management is the correlation of user's HTTP request with the stored session. With Spring Session's Servlet API support this is the responsibility of HttpSessionIdResolver
, and by default Spring Session uses cookie based implementation i.e. CookieHttpSessionIdResolver
. There's also an HTTP header based implementation in HeaderHttpSessionIdResolver
. I'm stating this because it's important to realize that session storage are distinct concerns that operate on different levels.
现在,关于 CookieHttpSessionIdResolver
,它将 cookie 写入和读取问题委托给 CookieSerializer
(DefaultCookieSerializer
是......好吧,默认执行).根据其配置,DefaultCookieSerializer
在写入和读取会话 cookie 时会考虑多个选项,即 cookie 名称、是否对 cookie 值进行 Base64 编码、是否使用 httpOnly
cookie 指令等.
Now, regarding the CookieHttpSessionIdResolver
, it delegates cookie writing and reading concerns to CookieSerializer
(with DefaultCookieSerializer
being the... well, default implementation). According to its configuration, DefaultCookieSerializer
will respect a number of options when writing and reading session cookies i.e. cookie name, whether to Base64 encode cookie value, whether to use httpOnly
cookie directive etc.
但是,我无法获得服务器关联,因为当我调试 HttpServletRequest 进入我的 Spring 应用程序时,HttpServletRequest.getSession().getId() 中没有 jvmRoute(尽管十六进制数与我的匹配)在 Chrome 中查看),这就是我传递给 Talend 作业的内容.
这是我不明白的部分 - 如果你能够从当前的 HttpServletRequest
解析 HttpSession
那么你就知道什么是 jvmRoute代码> 它一定对吗?它是当前 JVM 的
jvmRoute
,否则 session 不会被解析 HttpServletRequest
由这个 JVM 处理.
This is the part that I don't understand - if you're able to resolve HttpSession
from the current HttpServletRequest
then you know what jvmRoute
it's bound to right? It's the jvmRoute
of the current JVM, otherwise session wouldn't be resolved HttpServletRequest
in handled by this JVM.
Spring Session 和 Tomcat 的会话管理的不同之处在于,对于 Tomcat,jvmRoute
是 会话 id 生成相关问题 而对于 Spring Session,jvmRoute
用于会话 cookie 序列化的上下文中.
What's different between the Spring Session and Tomcat's session management, is that with Tomcat the jvmRoute
is session id generation related concern while with Spring Session the jvmRoute
is used in the context of session cookie serialization.
这篇关于SpringSession DefaultCookieSerializer.setJvmRoute 有效,但 HttpServletRequest 没有所需的 jvmRoute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!