Multithreading 微服务体系结构中的分布式锁

Multithreading 微服务体系结构中的分布式锁,multithreading,microservices,semaphore,redisson,distributed-lock,Multithreading,Microservices,Semaphore,Redisson,Distributed Lock,我们有一个架构设置,其中客户端应用程序在服务器中运行,我们希望有一个微型服务负责提供分布式锁/映射/缓存功能。这个微服务在内部使用Redisson,这是一个基于java的客户端,可以与Redis对话。现在,我们希望提供客户端应用程序可以使用的微服务的API锁定、解锁、获取和放置。对于应用程序到微服务的通信,我们将使用gRPC协议 从Microservice向客户端提供锁定/解锁API的正确方式是什么? 目前,我们使用Redisson的基于RedissonMap RMap.getLock(..)的

我们有一个架构设置,其中客户端应用程序在服务器中运行,我们希望有一个微型服务负责提供分布式锁/映射/缓存功能。这个微服务在内部使用Redisson,这是一个基于java的客户端,可以与Redis对话。现在,我们希望提供客户端应用程序可以使用的微服务的API锁定、解锁、获取和放置。对于应用程序到微服务的通信,我们将使用gRPC协议

从Microservice向客户端提供锁定/解锁API的正确方式是什么? 目前,我们使用Redisson的基于RedissonMap RMap.getLock(..)的Semapbased,它遵循java锁规范,所以获取分布式锁的线程只能解锁。这样做的一个问题是,由于锁定是由微服务处理的,所以客户端必须发出单独的锁定和解锁请求,这些请求可能由相同的节点(微服务)和相同的线程提供,也可能不由相同的节点(微服务)和线程提供。这可以通过使用信号量解决(有1个许可证)。因此,本质上,我们使用redisson的Rsemaphore服务于互斥用例

我更感兴趣的是,当我们为acquire/release制定API规范时,应该考虑哪些因素,比如在微服务上对acquire/release许可的调用应该是同步的还是异步的

比如在微服务上获取/释放许可的调用应该是同步的还是异步的

这取决于信号量所执行的逻辑。仅对acquire/release块内执行的异步逻辑使用async way。

我有一个类似的问题——在某个时候——除非是“轮询”,否则只有微服务必须阻塞客户端以等待信号量完成。 如果阻塞是不可接受的,那么就不需要信号量。 即使每个调用来自不同的JVM(可能是从该JVM到redis的初始连接),以下逻辑也应该可以正常工作-- 仅暂时使用一个RLock对象或一个原子对象——足够长的时间以使用某种唯一ID(由客户端或microservice提供)更新密钥或映射条目。 然后将其“安全”存储在Redis中,并指示类似于“锁”的内容。 如果您在钥匙上使用过期,则会在“锁”上显示TTL

如果您的应用程序在等待信号量释放时可以阻塞微服务,那么来自不同微服务的呼叫应该可以正常工作。这是相同的模型,就像有两个长期运行的JVM直接连接到redis/redisson,但每个JVM只使用一次信号量

你不能(轻松地)做的是,当你回到客户机时,仍然“持有”一个“锁”
然后稍后调用一个(不同的JVM)微服务来释放锁。

我问你为什么想要“让一个微服务负责提供分布式锁/映射/缓存功能”。您可以部署一些预先存在的协调服务,它们已经可以为您提供此类功能,如ZooKeeper或etcd。至于“异步vs同步”,如果您使用gRPC,在API级别上是不相关的,因为gRPC同时支持这两种功能,客户端可以使用他们想要的任何一种。当我说从微服务提供锁定功能时,我并不是在重新发明任何新功能。。这只是为了从核心应用程序中摆脱对第三方服务的依赖。关于sync vs async,我所担心的是,由于在高并发性下,acquire/lock api可能会保持连接更长的时间,因此使acquire/lock api同步是否是一种好的做法。。这是否偏离了微服务的标准实践