RESTful API必须是无状态的,但是并发性呢?

时间:2012-03-23 20:14:02

标签: api rest concurrency stateless

我很好奇我如何解决RESTful API的并发问题。更具体地说,我有一组需要手动检查和更新的对象,例如:需要手动更新列的行数;但是,如果我向多个客户端打开API,他们都将从上到下抓取这些项目,因此许多用户将同时填充同一行的列。我宁愿没有冲突,简单,有状态的方法是将项目转储到服务的队列中,并在人们请求时将其弹出。

这是什么无状态版本?按IP地址哈希,还是根据id随机抓取行?

:: update ::

“嗯,从客户的角度来看,它必须只是无国籍?

这当然很有意义。我刚刚阅读了一篇关于RESTful API的文章(ibm.com/developerworks/webservices/library/ws-restful),在遇到有关分页的问题之后,我担心我的状态非常好的队列类似于页面递增,但是它们实际上是完全不同的,因为“下一页”在客户端是相对的,而“pop”对于客户端来说总是无状态的:以前弹出的内容并不重要。

感谢清除我的头脑!“ - 我

3 个答案:

答案 0 :(得分:5)

您可以采取两种基本方法:

  1. 完全无国籍,并采取“最后请求获胜”策略。虽然听起来很奇怪,但在客户端和服务器端的可预测性,可伸缩性,代码复杂性和实现方面,它可能是最干净的解决方案。它还有很多优先权:看一下像Google这样的网站如何使用start=10进行第2页的分页,start=20进行第3页分页,等等。

    您可能会发现,当您在页面之间来回导航时,内容会在页面内发生变化,但那又是什么?您始终可以获取最新信息,Google可以在任意服务器上处理您的请求,而无需查找会话信息以确定您的上一个查询背景。

    这种方法的最大优点是服务器实现的简单性。每个请求都可以直接传递到后端的数据层,并且在HTTP级别(通过E-Tags或Last-Modified标头)和服务器端(使用类似memcache的内容)进行缓存绝对成熟。例子)。

  2. 继续有状态,找出一种方法让您的服务器为每个API“会话”发出某种每客户端锁或令牌。这就像试图用棍子打击海洋的潮流,因为你最终会失败和沮丧。

    您如何识别客户?会话密钥? IP地址?他们所在的套接字的文件描述符(祝你好运,如果你使用像HTTP这样的传输,可以在请求之间关闭连接......)?您为此选择的详细信息必须保留在服务器端,或者您必须在应用服务器上使用一些讨厌的旧粘性会话功能(如果是这样,如果他们使用的服务器出现故障,天堂会帮助您的客户端中期会议)。

    您将如何处理不合理地消失的API客户端?是否会通过收割者线程清理空闲的线程来自动超时会话锁定?这是更多的代码,更复杂,更多的地方可以隐藏错误。那些从很长的空闲时间回来并尝试重用过期锁的API客户端怎么样,应该如何构建客户端应用程序来处理这种情况呢?

  3. 我可以继续,但希望你能看到我的观点。选择1,然后去无状态。否则,您最终将尝试在服务器端跟踪客户端状态。 唯一应跟踪客户状态的是客户本身。

答案 1 :(得分:1)

维护资源状态是可以的。 “无国籍禁令”仅指会议状态。

以下摘自Roy Fielding's seminal REST derivation

  

我们接下来为客户端 - 服务器交互添加一个约束:   沟通必须是无国籍的,就像在   第3.4.3节(图5-3)的客户端无状态服务器(CSS)样式,   这样从客户端到服务器的每个请求都必须包含所有   理解请求所必需的信息,不能采取   服务器上任何存储上下文的优点。会话状态是   因此完全留在客户端。

答案 2 :(得分:0)

遇到这个问题,寻找处理并发的最佳实践, 从答案中可以看出答案中缺少对“Optimistic Concurrency”的任何引用。