.NET應用中的高效分布式同步解決方案
前言
在分布式系統中,多個線程、進程或服務之間常常需要并發訪問共享資源,這就帶來了數據同步與一致性的挑戰。今天大姚給大家分享一個.NET應用中的高效分布式同步解決方案:DistributedLock。
項目介紹
DistributedLock 是一個 .NET 開源的庫,它基于多種底層技術提供了強大且易于使用的分布式互斥鎖、讀寫鎖和信號量。確保多個線程、進程或服務能夠安全、協調地訪問共享資源,防止競態條件,維護數據一致性。
多種技術的實現方案
DistributedLock 提供了基于多種技術的實現方案,你可以單獨安裝所需的實現包,也可以直接安裝 DistributedLock NuGet 包使用。
圖片
項目源代碼
圖片
DistributedLock 包安裝
在 NuGet 包管理器中搜索:DistributedLock
安裝。
圖片
在 ASP.NET Core 應用中使用
對于使用依賴注入的應用程序,DistributedLock 的提供程序可以輕松地將鎖(或其他原語)名稱的規范與其其他設置(如數據庫連接字符串)分離開來。例如,在一個 ASP.NET Core 應用程序中,你可以這樣做:
Program.cs 中注冊
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
// 注冊一個單例的 IDistributedLockProvider,使用 Postgres 作為底層實現
builder.Services.AddSingleton<IDistributedLockProvider>(_ => new PostgresDistributedSynchronizationProvider(myConnectionString));
builder.Services.AddTransient<UserAccountService>();
對賬戶進行同步的初始化操作
public class UserAccountService
{
private readonly IDistributedLockProvider _synchronizationProvider;
/// <summary>
/// 構造函數,接受 IDistributedLockProvider 的注入
/// </summary>
/// <param name="synchronizationProvider">synchronizationProvider</param>
public UserAccountService(IDistributedLockProvider synchronizationProvider)
{
this._synchronizationProvider = synchronizationProvider; // 將注入的 IDistributedLockProvider 賦值給私有字段
}
public void InitializeUserAccount(int id)
{
// 使用提供者來構造一個鎖
var currentLock = this._synchronizationProvider.CreateLock($"UserAccount{id}"); // 根據用戶賬戶ID創建一個鎖
using (currentLock.Acquire()) // 獲取鎖,并在 using 塊結束時自動釋放
{
// 執行操作(在鎖保護下)
}
// 或者,對于常見用例,擴展方法允許通過單個調用來完成此操作
using (this._synchronizationProvider.AcquireLock($"UserAccount{id}")) // 直接使用提供者的擴展方法來獲取并釋放鎖
{
// 執行操作(在鎖保護下)
}
}
}
基于 Redis 實現的分布式鎖
DistributedLock.Redis 包提供了基于 Redis 實現的分布式鎖功能,如下所示:
- 實現說明:https://redis.io/docs/latest/develop/use/patterns/distributed-locks
var connectionString = "redis鏈接";
var connection = await ConnectionMultiplexer.ConnectAsync(connectionString); // uses StackExchange.Redis
var currentLock = new RedisDistributedLock("MyLockName", connection.GetDatabase());
await using (var handle = await currentLock.TryAcquireAsync())
{
if (handle != null)
{
//我已經獲取了鎖
}
}
基于 ZooKeeper 實現的分布式鎖
DistributedLock.ZooKeeper 包提供過了基于 Apache ZooKeeper 提供的分布式鎖功能,如下所示:
- 實現說明:https://zookeeper.apache.org/doc/r3.1.2/recipes.html
var currentLock = new ZooKeeperDistributedLock("MyLockName", connectionString);
await using (await currentLock.AcquireAsync())
{
// 我已經獲取了鎖
}
項目源碼地址
更多項目實用功能和特性歡迎前往項目開源地址查看??,別忘了給項目一個Star支持??。
- GitHub開源地址:https://github.com/madelson/DistributedLock