java 无状态服务器如何工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4495950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do stateless servers work?
提问by cometta
I try to understand this. Normally each time user login system, server side will create a session, while user client side there is cookie. When people talk about stateless serverside, stateful client side, what do they mean? server side no need use session keep track user? only use cookies on client side to check user? mean if I change server, user will not notice it and still can resume using the service?
我试图理解这一点。通常每次用户登录系统时,服务器端都会创建一个会话,而用户客户端则有 cookie。当人们谈论无状态服务器端、有状态客户端时,它们是什么意思?服务器端不需要使用会话跟踪用户?只在客户端使用 cookie 来检查用户?意思是如果我更换服务器,用户不会注意到它,仍然可以继续使用该服务?
How to configure spring-security to to do this?
如何配置 spring-security 来做到这一点?
回答by chubbsondubs
Tracking a user across servers is tricky for true stateless server side. Most of the time things are sorta stateless server where logins are the exception. However, the big deal with stateless servers is that it makes clustering very simple so you can scale horizontally.
对于真正的无状态服务器端来说,跨服务器跟踪用户是很棘手的。大多数情况下,事情是某种无状态服务器,其中登录是例外。然而,无状态服务器的重要之处在于它使集群变得非常简单,因此您可以水平扩展。
In Java you can make it stateless using either cookies to store credentials, or using distributed hashes. Generally, people accept using something like memcache and say they are stateless because the state is stored outside the webserver. That allows the user to use any webserver in the farm and still be safely authenticated. In Java we have plenty of distributed hash implementations that you can use with spring so you don't have to use memcache to do this.
在 Java 中,您可以使用 cookie 存储凭据或使用分布式哈希使其无状态。通常,人们接受使用诸如 memcache 之类的东西并说他们是无状态的,因为状态存储在网络服务器之外。这允许用户使用场中的任何网络服务器,并且仍然可以安全地进行身份验证。在 Java 中,我们有很多分布式哈希实现可以与 spring 一起使用,因此您不必使用 memcache 来执行此操作。
The other option is to use cookies to store a cryptographic secure hashed ticket called an HMAC. Using cookies avoids using the Session so the webserver is stateless. With HMAC you can sign a block of data that cannot be forged or created by a 3rd party and is guaranteed to be originated from you. This doesn't require outside server resources (the cache) to authenticate the user so it can scale better, but there are some security concerns you have to be aware of. FYI Google uses this technique to scale horizontally. One HMAC's aren't like SHA1 or other cyrpto-hashes. They require a secret key that has to be on each server in the farm. That also has to be protected with symmetric encryption key to make sure it's stored securely on the server should someone get ahold of the file. Also HMACs information is stored in the clear so while you can put the username or email in the cookie the actual crypto hash is available to anyone. If someone were to get ahold of that cookie they could masquerade as that user. That's why HMACs are typically valid for only a certain amount of time. After that they expire so if someone does get ahold of them they can't access that account forever.
另一种选择是使用 cookie 来存储称为 HMAC 的加密安全散列票证。使用 cookie 避免使用会话,因此网络服务器是无状态的。使用 HMAC,您可以签署无法由第三方伪造或创建的数据块,并保证来自您。这不需要外部服务器资源(缓存)来对用户进行身份验证,因此它可以更好地扩展,但是您必须注意一些安全问题。仅供参考,谷歌使用这种技术水平扩展。一个 HMAC 不像 SHA1 或其他密码哈希。它们需要一个密钥,该密钥必须位于场中的每台服务器上。这还必须使用对称加密密钥进行保护,以确保在有人获取文件时将其安全地存储在服务器上。此外,HMAC 信息以明文形式存储,因此当您可以将用户名或电子邮件放入 cookie 时,任何人都可以使用实际的加密哈希。如果有人要获得那个 cookie,他们就可以伪装成那个用户。这就是 HMAC 通常仅在一定时间内有效的原因。之后它们就会过期,所以如果有人确实得到了它们,他们就无法永远访问该帐户。
So HMACs have this weakness and you should be careful about what applications you use them in. It would be a really bad idea for Paypal to use this scheme because all I have to do is get your secure cookie then transfer all your funds to me. The big upside is everything is your app is truly stateless.
所以 HMAC 有这个弱点,你应该小心你在哪些应用程序中使用它们。 Paypal 使用这个方案是一个非常糟糕的主意,因为我所要做的就是获取你的安全 cookie,然后将你的所有资金转移给我。最大的好处是你的应用程序是真正无状态的。
The final option is to store your java sessions in a distributed hash. Php and other platforms will dump their sessions in the database, the poor mans distributed cache, or dump them into memcache. With Java you can do the same thing. You can put your session objects into the distributed cache too. This option has fallen out of favor because people think "cool now I can dump whatever I want into my session and it will be stateless." However, as with all distributed caches there are limits on transfer speed, replication time, and payload size are linked. This is true for Java or Memcache. Keep your sessions small, and this works well. Throw everything into the session and you go right back to scaling issues you have with a single server. And really it's probably worse than if you had just made your server stateful because sometimes grid computing is worse than single server.
最后一个选项是将您的 java 会话存储在分布式哈希中。php等平台会把自己的session dump到数据库中,可怜的mans分布式缓存,或者dump到memcache中。使用 Java,您可以做同样的事情。您也可以将会话对象放入分布式缓存中。这个选项已经失宠,因为人们认为“现在很酷,我可以将任何我想要的东西转储到我的会话中,而且它将是无状态的。” 但是,与所有分布式缓存一样,传输速度、复制时间和有效负载大小都有限制。这适用于 Java 或 Memcache。保持你的会话小,这很有效。将所有内容都放入会话中,然后您将立即返回到单个服务器的扩展问题。真的是'
Update: Here are a list of Java distributed caching libraries you can use to do this:
更新:以下是可用于执行此操作的 Java 分布式缓存库列表:
http://www.manageability.org/blog/stuff/distributed-cache-java
http://www.manageability.org/blog/stuff/distributed-cache-java
回答by weltraumpirat
A statelessservice is a service that does not store any data on the application server. It reads or writes data to the database, returns a value (or not), and after that, any information on the task itself is forgotten.
一个无状态的服务是不存储任何数据应用服务器上的服务。它向数据库读取或写入数据,返回一个值(或不返回),然后,任务本身的任何信息都会被遗忘。
A statefulservice is used to perform transactions, that is a series of tasks that depend on the result of preceding tasks. The easiest example is sending an order at a web store, where you gather your products in a shopping cart, and when you check out, you enter your account data on one page, store it, then enter your billing address, store it, then confirm your order and conclude the transaction. Each step depends on the successful outcome of the preceding step, and data needs to be preserved until the last one of these steps is completed or the transaction is canceled, in which case there has to be a rollback to restore your account balance to the way it was before you checked out.
有状态服务用于执行事务,即一系列依赖于先前任务结果的任务。最简单的例子是在网上商店发送订单,在那里您将产品收集在购物车中,当您结账时,您在一个页面上输入您的帐户数据,存储它,然后输入您的帐单地址,存储它,然后确认您的订单并完成交易。每一步都取决于上一步的成功结果,数据需要保留到最后一步完成或者交易被取消,这种情况下必须进行回滚才能将您的账户余额恢复到原样是在你退房之前。
In most cases, you can implement transactions both ways, but if you were to use stateless services, your client application would have to take care of handling the proper order and completion of tasks, or you would have to find some other way to store the transaction information correctly and manage the rollbacks. That would be a stateful client-side, as you called it.
在大多数情况下,您可以通过两种方式实现事务,但是如果您要使用无状态服务,您的客户端应用程序将不得不处理正确的顺序和任务的完成,或者您必须找到某种其他方式来存储这些交易信息正确并管理回滚。这将是一个有状态的客户端,正如你所说的那样。
All of this is, however, quite general, and security and/or session handling would have to be considered in each of those cases. You can very well use session information to authenticate stateless service calls - you will just have to authenticate each call individually, for example by attaching a session id or user id or some other security token to the business data.
然而,所有这些都是非常普遍的,并且在每种情况下都必须考虑安全性和/或会话处理。您可以很好地使用会话信息来验证无状态服务调用——您只需要单独验证每个调用,例如通过将会话 ID 或用户 ID 或其他一些安全令牌附加到业务数据。