1

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

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

我更感兴趣的是找出当我们提出获取/释放的 API 规范时需要考虑的因素,比如在微服务上对获取/释放许可的调用应该是同步的还是异步的。

4

2 回答 2

1

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

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

您不能(轻松地)做的是在您返回客户端时仍然“持有”一个“锁”,然后再调用(不同的 JVM)微服务来释放锁。

于 2020-03-29T13:04:21.407 回答
0

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

这取决于信号量强制执行的逻辑。仅对在获取/释放块内执行的异步逻辑使用异步方式。

于 2020-02-07T09:52:46.797 回答