无状态服务器如何工作?

Posted

技术标签:

【中文标题】无状态服务器如何工作?【英文标题】:How do stateless servers work? 【发布时间】:2011-05-28 14:42:33 【问题描述】:

我试图理解这一点。通常用户每次登录系统时,服务器端都会创建一个会话,而用户客户端则有cookie。当人们谈论无状态服务器端、有状态客户端时,它们是什么意思?服务器端不需要使用会话跟踪用户?仅在客户端使用 cookie 来检查用户?意思是如果我更改服务器,用户不会注意到它并且仍然可以继续使用该服务?

如何配置 spring-security 来做到这一点?

【问题讨论】:

我建议在单独的问题中询问 spring-security 配置,因为答案与解释什么是无状态服务器的答案大不相同。 【参考方案1】:

跨服务器跟踪用户对于真正的无状态服务器端来说是很棘手的。大多数情况下,登录是例外的无状态服务器。但是,无状态服务器的重要之处在于它使集群变得非常简单,因此您可以水平扩展。

在 Java 中,您可以使用 cookie 存储凭据或使用分布式哈希使其无状态。通常,人们接受使用 memcache 之类的东西并说他们是无状态的,因为状态存储在网络服务器之外。这允许用户使用农场中的任何网络服务器,并且仍然可以安全地进行身份验证。在 Java 中,我们有大量的分布式哈希实现,您可以将它们与 spring 一起使用,因此您不必使用 memcache 来执行此操作。

另一种选择是使用 cookie 来存储称为 HMAC 的加密安全散列票证。使用 cookie 可避免使用 Session,因此网络服务器是无状态的。使用 HMAC,您可以签署无法由第三方伪造或创建的数据块,并保证来自您。这不需要外部服务器资源(缓存)来对用户进行身份验证,因此可以更好地扩展,但是您必须注意一些安全问题。仅供参考 Google 使用这种技术进行水平扩展。一个 HMAC 不像 SHA1 或其他密码哈希。他们需要一个密钥,该密钥必须位于场中的每台服务器上。这也必须使用对称加密密钥进行保护,以确保在有人获得文件时将其安全地存储在服务器上。此外,HMAC 信息以明文形式存储,因此当您可以将用户名或电子邮件放入 cookie 时,任何人都可以使用实际的加密哈希。如果有人要获取该 cookie,他们可以伪装成该用户。这就是为什么 HMAC 通常只在一定时间内有效。之后它们就会过期,因此如果有人确实获得了它们,他们将永远无法访问该帐户。

所以 HMAC 有这个弱点,你应该小心你在哪些应用程序中使用它们。Paypal 使用这个方案是一个非常糟糕的主意,因为我所要做的就是获取你的安全 cookie,然后转移你所有的资金对我来说。最大的好处是您的应用是真正无状态的。

最后一个选项是将您的 java 会话存储在分布式哈希中。 php等平台会将自己的sessiondump到数据库中,可怜的mans分布式缓存,或者dump到memcache中。使用 Java,您可以做同样的事情。您也可以将会话对象放入分布式缓存中。这个选项已经失宠了,因为人们认为“很酷,现在我可以将任何我想要的东西放到我的会话中,它将是无状态的。”但是,与所有分布式缓存一样,传输速度、复制时间和有效负载大小都有限制。这适用于 Java 或 Memcache。保持你的会话小,这很好用。将所有内容都放入会话中,然后您就可以回到使用单个服务器时遇到的扩展问题。实际上,这可能比刚刚使服务器有状态更糟糕,因为有时网格计算比单个服务器更糟糕。

更新:以下是可用于执行此操作的 Java 分布式缓存库列表:

http://www.manageability.org/blog/stuff/distributed-cache-java

【讨论】:

@chubbsondubs 谢谢你的解释。我还想正确理解会话、cookie、令牌、HTTP 身份验证概念。您能否向我解释一下这些概念,或者提供一个很好的资源。如果需要,我可以为此创建一个单独的问题。我可以开发一个小型的工作演示来了解 cookie、会话、http 身份验证吗?【参考方案2】:

无状态服务是一种不在应用服务器上存储任何数据的服务。它读取或写入数据到数据库,返回一个值(或不返回),然后,任务本身的任何信息都被遗忘了。

有状态服务用于执行事务,即依赖于先前任务结果的一系列任务。最简单的例子是在网上商店发送订单,您在购物车中收集产品,结帐时,您在一个页面上输入您的帐户数据,存储它,然后输入您的帐单地址,存储它,然后确认您的订单并完成交易。每一步都取决于上一步的成功结果,并且需要保留数据直到这些步骤中的最后一个步骤完成或交易被取消,在这种情况下必须进行回滚以恢复您的帐户余额的方式那是在你退房之前。

在大多数情况下,您可以通过两种方式实现事务,但如果您要使用无状态服务,您的客户端应用程序必须负责处理任务的正确顺序和完成,或者您必须找到其他方式正确存储事务信息并管理回滚。这将是一个有状态的客户端,正如你所说的那样。

然而,所有这些都是相当笼统的,在每种情况下都必须考虑安全性和/或会话处理。您可以很好地使用会话信息来验证无状态服务调用 - 您只需单独验证每个调用,例如通过将会话 ID 或用户 ID 或其他一些安全令牌附加到业务数据。

【讨论】:

以上是关于无状态服务器如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

#yyds干货盘点# Kubernetes 如何通过 StatefulSet 支持有状态应用?(07)

如何访问无状态服务的特定副本

如何访问 Azure Service Fabric 有状态/无状态服务中的 settings.xml?

如何实现无状态烧瓶 webapp

如何理解“RESTful API 是无状态的”?

如果资源服务器应该是无状态的,如何使用 websocket 将消息发送到队列