你们在实际项目中看到什么样的服务器?
1)Web服务必须是无状态的:基本上你必须为每个请求发送用户名/密码,每个请求必须使用HTTPS,我会在每次需要时验证并加载User对象。
2)Web服务会话:就像在Web容器中一样,因此我至少可以保存经过身份验证的User对象并具有类似于会话ID的内容,因此我不需要对每个用户进行身份验证,加载和检查请求。
3)粘性服务(跨请求的持久服务):https://jax-ws.dev.java.net/nonav/2.1/docs/statefulWebservice.html
我理解有状态服务(以及Web应用程序会话)的可伸缩性问题,但有时您必须具有某种状态,例如购物车。但是您也可以将此状态置于数据库中(将后端用作一种会话 argh )或将整个状态传递给客户端(客户端负责重新发送整个购物车)
事实是,至少对于Web应用程序,会话在许多情况下都有很大帮助。如果您的系统接受“如果他的Web服务器发生故障,用户必须重新开始做任何事情”,或者如果这是不可接受的话,您可以尝试会话群集,则可以忽略可伸缩性问题。
Web服务如何?我倾向于得出结论,Web服务与Web应用程序非常不同,并且接受选项1)(总是无状态),但是根据实际项目经验听取其他意见会很好。
答案 0 :(得分:18)
虽然这只是一个很小的差异,但仍应提及:
Web服务中的状态不会导致可伸缩性,而是在App Server 上的状态,它将托管将破坏可伸缩性的Web服务。当您说该用户需要访问此服务器时(就像在粘性会话中一样),您实际上限制了您的可伸缩性选项。您要达到的目的是“任何免费负载均衡的App服务器”都可以处理此Web服务请求,如果我再添加1个App Server,我应该能够处理更多用户 。
如果您希望维护状态以传递身份验证令牌并且在每个请求上获得服务以从数据存储中检索您的“状态”(最好是冗余和分区的,例如分布式的),那就完全正常(并且个人推荐) +复制的键/值数据存储)。这就是亚马逊用SimpleDb和谷歌与BigTable一起做的事情。
Ebay采用略有不同的方法,并将大多数客户端状态存储在cookie中,以便随每个请求传入。虽然它可以产生更多的流量,但它仍然可以扩展,因为它们的任何服务器仍然可以处理请求。
如果您想要一个可扩展的数据存储,我建议您查看redis它具有无法在键/值数据存储中击败的速度和功能。
如果您想获得有关如何构建快速和可扩展服务的优质材料,还应该查看highscalability.com。
答案 1 :(得分:6)
理想情况下,webservices(和网站)应该是无状态的。
不幸的是,这需要经过深思熟虑的问题领域,以及明确的关注点分离。
我发现在实践中大多数现实网站依赖于状态,即使这会限制其可扩展性。
我还发现很多真实世界网络服务也依赖于州。
最终,“正确”决策是针对特定问题的决策,因此编写依赖于状态的Web服务并在以后如果可伸缩性成为问题而重构它可能是可以的。
答案 2 :(得分:2)
高度依赖于服务是否是单一事务导向(例如获取股票报价),或者服务的输出是否依赖于跨多个事务从特定客户端提供的数据(在这种情况下必须保持状态。)< / p>
就可伸缩性问题而言,将状态存储在数据库中实际上并不是一种糟糕的方法(事实上,如果您在服务器场中对服务进行负载平衡,它可能是唯一的方法。)
答案 3 :(得分:0)
我认为对于Flex客户端,状态将从服务中移出并进入客户端层。保持服务无状态,让客户端保持所需的状态。服务保持简单,客户可以随意将它们混合在一起。
答案 4 :(得分:0)
您似乎将状态和身份验证等同起来。也许你习惯于在会话状态下存储用户名和密码?
即使使用旧的ASMX Web服务,也没有必要这样做。只需将您需要的任何信息传递给“登录”操作即可。此操作将被定义为返回“身份验证票证”标题。
需要身份验证的所有其他操作都需要此“身份验证票证”标头。他们将分别检查标头是否代表有效的,经过身份验证的用户。如果是这样,那么他们将执行他们的任务。如果没有,那么它们将返回SOAP Fault,指示需要进行身份验证。
不需要任何州。只需确保可以在运行服务的任何服务器上验证身份验证票证(例如,在Web场中),您就可以了。