Java Web 应用程序中的会话变量存储在哪里?

10

1 - Java Web应用中的会话变量存储在哪里?在客户端还是服务器端?

2 - 如果我通过会话(session)把大量的对象和变量传递,那么它会减慢客户端请求的速度吗?

P.S. 在我的情况下,我使用 Spring MVC

3个回答

14

"session"变量由两部分组成,一个非常小的会话标识符,存储在客户端上,通常命名为jSessionId并存储为cookie。但是,sessionId也可以编码到URL中。

会话的第二个部分是实际数据,它存储在服务器上,如果您的服务器是多服务器集群的一部分,则可能存储在服务器端数据库中。每个会话都由该sessionId标识,并且客户端在每个请求中都发送它。这就是为什么它被设计得非常小的原因。


1
我理解Servlet和JSP,我只是想问一下,如果会话变量在客户端有一点存储空间,为什么我们不仅使用会话变量而不是请求变量,需要在每个请求中加载它们。 - Hayi
1
仅使用会话变量的缺点是什么? - Hayi
1
@Aminoo 如果您在集群会话中,变量必须被序列化并(通常)写入数据库。请求变量则不需要。此外,您在会话中存储的内容越多,您的应用程序通常就会变得越慢、扩展性也会降低。 - Elliott Frisch
我们的Web应用部署在5个不同服务器(Tomcat 7)上,并且所有这些服务器都在LB后面。我们遇到的问题是,当一个用户登录并点击任何菜单时,它会再次重定向到登录页面,这是因为LB正在发送第二个请求到其会话未创建的其他服务器。为了避免这种情况,我们已经启用了LB上的持久会话,以便一旦请求进入某个服务器,它将始终发送到同一个服务器。但由于这样做,所有5个服务器都没有按预期使用。所以,在Java(Spring)中是否有类似.NET中的“session state server”的解决方法? - Amogh
发送每个请求时都带上 jSessionId 并不能解决这个问题,我猜是这样的。如果我错了,请纠正我。如果客户端浏览器禁用了 cookies,那么 jSessionId 将如何存储? - Amogh
显示剩余11条评论

8
简单地说,您的会话数据存储在服务器端。Web浏览器只会获取一个用于识别其会话的字符串ID。
实际上,Spring Security更加重视会话信息,因为即使用户没有登录,会话可能根本不存在。
当我仅使用Spring MVC时,我不使用会话来存储重要数据,因为会话仅存储在内存中,是为临时保存数据而设计的。
当我使用Spring Security时,我必须将许多重要内容存储在内存中,例如帐户数据,这些数据不能通过Internet传输,并且我不想每次从数据库中加载它们。因此,我必须选择会话。
因此,当存储登录会话的服务器宕机时,所有已登录到该服务器的用户都必须重新登录以检索另一个会话ID。
会话并不总是最佳选择,因为当我们有许多使用会话数据的服务器时,我必须在所有服务器之间共享数据,无论如何,网络IO对服务器来说都很昂贵。

如果客户端只存储了一个字符串ID,为什么我们不将所有变量都设置为会话变量而不是请求变量/属性? - Hayi
2
关于服务器端会话变量存在许多问题。最大的问题是服务器可扩展性和性能。考虑一下,如果你有很多服务器,其中一个宕机了,会发生什么?这个服务器中的会话数据将会丢失。当然,你可以将会话数据存储在数据库或内存缓存服务器中,但这意味着所有会话操作都会触发网络IO,这会带来很大的开销。 - Doug Hou
如果服务器宕机,我们可以从中检索数据,除非它着火了 :-D - Hayi
很抱歉,您无法获取会话数据,因为会话数据仅存储在内存中,当服务器关闭时,您将失去所有内存中的数据。 - Doug Hou
确定只是在内存中吗?如果服务器重新启动,每个人都必须再次登录吗? - Hayi
1
@Aminoo 是的,如果你没有特殊的配置,会话数据就在内存中,因为这是加载数据最有效的方式。这就是为什么许多程序员讨厌服务器端状态的原因。 - Doug Hou

1

1.它存储在服务器上 2.Session 存储在服务器上,因此您在其中设置的对象也可能存储在服务器上。请求仅向服务器发送 SessionId 以标识该用户的 Session 给其他用户的 Session。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接