rest - 在分布式环境中调用一堆 REST API
问题描述
我在 python 库中有我的应用程序逻辑。我的库提供的每个操作都涉及调用一些 REST api 一次或多次。所以我有:
def OperationA(resource_id, params):
Call REST Api /X/resource_id/params
Call REST Api /Y/resource_id/params
Call REST Api /Z/resource_id/params
def OperationB(resource_id params):
Call REST Api /R/resource_id//params
Call REST Api /S/resource_id//params
Call REST Api /T/resource_id//params
该库在分布式环境中执行,并调用操作以响应用户操作。因此,例如 OperationA 的两个实例可能同时执行。如果执行影响不同的资源,则同时运行操作是可以接受的。但是,影响相同资源的操作调用应按顺序执行。这是因为交叉调用 REST api 会导致 REST 服务的状态不一致。例如,如果 OperationA 在 id 为 3 的资源上同时执行,就会发生这种情况:
OperationA(3, "foo"): Call REST Api /X/3/foo
OperationA(3, "bla"): Call REST Api /X/3/bla
OperationA(3, "bla"): Call REST Api /Y/3/bla
OperationA(3, "foo"): Call REST Api /Y/3/foo
OperationA(3, "foo"): Call REST Api /Z/3/foo
OperationA(3, "bla"): Call REST Api /Z/3/bla
问题是最终端点 Y 处的资源 3 处于状态 foo 而在所有其他端点处资源处于状态 bla。
我可以在调用 REST api 之前获取分布式锁,但我还需要 REST api 本身的支持,正如Martin Kleppmann 指出的(以围栏令牌的形式),这是不可能的,因为我无法控制 REST api。
是否有一些现有的技术/服务可以用来防止不可接受的并发执行并且仍然能够水平扩展服务?
解决方案
如果您控制所有访问此 API 的客户端,您可以尝试通过一致的哈希来序列化对同一资源的所有访问——给定的资源将始终由同一台机器处理,然后您只需要获取本地锁。
如果有其他客户端同时访问此 API,并且该 API 没有为您的操作提供足够的表达能力(例如,只允许设置A
为10
,而不是允许说增量A
为1
),也没有任何条件/测试和设置更新(例如A
,10
如果其先前的值为 ),则设置为9
),也不是多键事务(例如A
,递增1
和递减B
2),也不是锁……您可能不走运,因为无法保证您想要的属性。
推荐阅读
- c++ - 无法使用 OpenCV 编译 c++ 程序。缺少 OpenCVConfig.cmake 文件
- javascript - jquery查找和长度
- c# - WCF Action attribute.change 导致客户端在更新服务引用时无法看到功能
- python-3.x - Datefinder Module Stranger 对特定字符串的行为
- java - 如何避免与放入不同模块的弹簧验证冲突?
- flutter - Flutter:我需要 Navigator 的特定实现方面的帮助
- python - 读取 ProteinNet 的 TFRecords 数据集
- c++ - 寻找整数中的重复模式
- web-services - 尝试获取类型数据库的实例时发生激活错误
- javascript - 如果用户第一次拒绝访问,请求许可 ReactNative