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