19

你们在实际项目中看到什么样的服务器?

1) Web 服务必须是无状态的:基本上你必须在每个请求中发送用户名/密码,每个请求都必须使用 HTTPS,如果需要,我将每次都验证并加载用户对象。

2) Web 服务的会话:就像在 Web 容器中一样,因此我至少可以保存经过身份验证的用户对象并具有类似于会话 ID 的内容,因此我不需要在每个请求上都进行身份验证、加载和检查用户。

3)Sticky Service(跨请求的持久服务):https ://jax-ws.dev.java.net/nonav/2.1/docs/statefulWebservice.html

我了解有状态服务(以及 Web 应用程序会话)的可伸缩性问题,但有时您必须拥有某种状态,例如购物车。但是您也可以将此状态放入数据库(将后端用作一种会话argh)或将整个状态传递给客户端(客户端负责重新发送整个购物车)。

事实是,至少对于 Web 应用程序,会话在许多情况下都有很大帮助。如果您的系统接受“如果他的 Web 服务器发生故障,用户必须重新开始他正在做的任何事情”,则可以忽略可伸缩性问题,或者如果这是不可接受的,您可以尝试使用会话集群。

Web 服务的情况如何?我倾向于得出结论,Web 服务与 Web 应用程序非常不同,并且接受选项 1)(总是无状态的),但很高兴听到基于实际项目经验的其他意见。

4

5 回答 5

19

虽然这只是一个很小的区别,但仍应提及:

杀死可扩展性的不是Web 服务中的状态,而是托管 Web 服务的应用服务器上的状态会杀死可扩展性。当你说这个用户需要访问这个服务器时(就像在粘性会话中所做的那样),你实际上是在限制你的可伸缩性选项。您想要达到的一点是“您的任何免费负载平衡应用服务器”都可以处理此 Web 服务请求,如果我再添加 1 个应用服务器,我应该能够处理 % more users

如果您想维护状态以传递身份验证令牌并在每个请求中获取服务以从数据存储中检索您的“状态”(最好是冗余和分区的,例如分布式+复制密钥),这完全可以(并且个人推荐) /值数据存储)。这就是 Amazon 使用 SimpleDb 和 Google 使用 BigTable 的方式。

Ebay 采用了一种稍微不同的方法,并将大多数客户端状态存储在一个 cookie 中,这样它就可以随每个请求一起传递。尽管它产生了更多的流量,但它仍然具有可扩展性,因为它们的任何服务器仍然可以处理请求。

如果您想要一个可扩展的数据存储,我建议您查看redis,它具有键/值数据存储无法比拟的速度和功能。

如果您想获得有关如何构建快速和可扩展服务的好资料,还应该查看highscalability.com 。

于 2010-02-09T23:39:07.757 回答
7

理想情况下,网络服务(和网站)应该是无状态的。

不幸的是,这需要经过深思熟虑的问题域和清晰的关注点分离。

我发现在实践中,大多数真实世界的网站都依赖于状态,即使这限制了它们的可扩展性。

我还发现许多现实世界的Web 服务也依赖于状态。

最终,“正确”的决定是针对特定问题的决定,因此编写一个依赖于状态的 Web 服务并在以后在可伸缩性成为问题时对其进行重构可能是可以的。

于 2009-06-17T22:46:03.667 回答
2

高度依赖于服务是否面向单一事务(例如获取股票报价),或者服务的输出是否依赖于跨多个事务的特定客户端提供的数据(在这种情况下,必须保持状态。)

就可伸缩性问题而言,将状态存储在数据库中实际上并不是一个糟糕的方法(事实上,如果您在服务器场中对服务进行负载平衡,这可能是唯一的方法。)

于 2009-06-17T22:45:14.153 回答
0

我认为对于 Flex 客户端,状态会从服务中移出并进入客户端层。保持服务无状态,让客户端维护所需的状态。服务保持简单,客户可以随意将它们混合在一起。

于 2009-06-17T23:20:41.867 回答
0

您似乎将状态和身份验证等同起来。也许您习惯于在会话状态中存储用户名和密码?

这不是必需的,即使使用旧的 ASMX Web 服务也是如此。只需将您需要的任何信息传递给“登录”操作即可。该操作将被定义为返回一个“Authentication Ticket”标头。

所有其他需要身份验证的操作都需要此“身份验证票证”标头。他们每个人都将检查标头以查看它是否代表一个有效的、经过身份验证的用户。如果是这样,那么他们将执行他们的任务。如果不是,那么它们将返回一个 SOAP 错误,指示需要进行身份验证。

不需要状态。只需确保可以在您的服务运行的任何服务器上验证身份验证票证(例如,在网络场中),您就可以了。

于 2009-06-17T23:28:04.143 回答