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































