我希望能够编写类似的代码
using (await LockAsync(x.Id))
{
// here goes code that is unsafe with respect to x.Id
// because it can be executed in multiple threads on
// the same instance or on multiple instances (e.g.
// multiple Azure Functions
}
我知道有一些开箱即用的方法可以在不使用密钥的情况下锁定整个执行上下文(例如函数中的
[ActivityTrigger]
),并且我知道我可以使用 blob 租约来滚动我自己的带钥匙的锁,但是有没有一种现成的方法? -钥匙锁的盒子方式?
是的,在 Azure 存储中确实如此,具有租赁 Blob 功能。 Azure Functions 实际上使用此功能来协调函数的多个实例。
如果我想获取
x.Id
上的锁,我将使用 Azure 存储在路径 /my-app-locks/{x.Id}
处的 0 字节 blob 上获得 60 秒的存储租用。如果我得到租约,我就知道我拥有锁,如果没有,那么其他人拥有锁,然后我可以轮询它,直到他们释放它。您也可以在 60s 租约到期前续签以延长时间。
此博客有一些代码和详细信息,以及其他实现方法 - https://medium.com/@fbeltrao/distributed-locking-in-azure-functions-bc4517c0306c
可以使用Redis分布式锁。
软件包 RedLock.net 恰好提供了您所需要的:
var resource = "the-thing-we-are-locking-on";
var expiry = TimeSpan.FromSeconds(30);
using (var redLock = await redlockFactory.CreateLockAsync(resource, expiry)) // there are also non async Create() methods
{
// make sure we got the lock
if (redLock.IsAcquired)
{
// do stuff
}
}
虽然不是“开箱即用”,但我发现了 2 个 Nuget 包,它们可以使用 Azure Blob 存储租赁(以及其他技术)来执行分布式锁。 YMMV: