10

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

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

:: 更新 ::

“嗯,所以从客户的角度来看,它一定是无国籍的吧?

这当然很有意义。我刚刚在阅读一篇关于 RESTful API 的文章 (ibm.com/developerworks/webservices/library/ws-restful),在遇到关于分页的一些信息后,我担心我的状态队列类似于按页递增,但是它们实际上完全不同,因为“下一页”在客户端是相对的,而“弹出”对于客户端始终是无状态的:之前弹出的内容无关紧要。

谢谢你让我头脑清醒!”——我

4

3 回答 3

5

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

  1. 完全无状态,并采用“最后请求获胜”策略。尽管听起来很奇怪,但就可预测性、可伸缩性、代码复杂性以及客户端和服务器端的实现而言,它可能是最简洁的解决方案。它也有很多优先级:看看像谷歌这样的网站是如何使用start=10for page 2、start=20for page 3 等对查询进行分页的。

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

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

  2. 进入有状态,并想办法让您的服务器为每个 API“会话”分配某种针对每个客户端的锁或令牌。这就像试图用一根棍子对抗海洋的潮汐,因为你最终会失败和沮丧。

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

    您将如何处理不正常消失的 API 客户端?你会通过让收割线程清理空闲的会话锁来自动超时他们的会话锁吗?那就是更多的代码、更多的复杂性和更多隐藏错误的地方。如果 API 客户端从长时间的空闲时间回来并尝试重新使用过期的锁,应该如何构建客户端应用程序来处理这种情况?

我可以继续,但希望你能明白我的意思。选择选项 1,然后变成无状态。否则,您最终将尝试在服务器端跟踪客户端状态。唯一应该跟踪客户端状态的是客户端本身。

于 2012-03-25T02:30:53.603 回答
1

可以保持资源状态。“无状态禁止”仅指会话状态。

以下是Roy Fielding 开创性的 REST 推导的摘录:

我们接下来为客户端-服务器交互添加一个约束:通信本质上必须是无状态的,如第 3.4.3 节(图 5-3)中的客户端-无状态-服务器(CSS)样式,这样从客户端到的每个请求服务器必须包含理解请求所需的所有信息,并且不能利用服务器上存储的任何上下文。因此,会话状态完全保留在客户端上。

于 2013-06-01T23:14:30.643 回答
0

遇到了这个问题,寻找处理并发的最佳实践,并且从答案中,答案中缺少“乐观并发”的任何参考。

于 2021-06-09T11:45:55.703 回答