我在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服务的状态不一致。例如,如果在ID为3的资源上同时执行OperationA,则会发生这种情况。
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 pointed out(以防护令牌的形式),这是不可能的,因为我无法控制REST api。
是否可以使用一些现有的技术/服务来防止无法接受的并发执行,并且仍然能够水平扩展服务?
答案 0 :(得分:1)
如果您控制所有访问此API的客户端,则可以尝试通过consistent hashing序列化对同一资源的所有访问-给定资源将始终由同一台机器处理,那么您只需要获取本地锁。
如果还有其他客户端同时访问此API,并且该API无法为您的操作提供足够的表现力(例如,仅允许将A
设置为10
,而不是说将A
递增1
),也不允许任何条件/测试和设置更新(例如,如果其先前值为{{,请将A
设置为10
) 1}}),也没有多键交易(例如,将9
递增A
,递减1
递增2)或锁定…您可能不走运,因为无法保证您想要的属性。