DistributedLock?實現.Net分布式鎖功能
在分布式系統(tǒng)中,經常會遇到多個實例同時訪問同一份資源的情況,例如:
- 多個服務節(jié)點同時寫入數據庫同一行數據
- 定時任務在多個節(jié)點上同時運行,導致重復執(zhí)行
- 多實例寫緩存時出現數據覆蓋問題
為了解決 并發(fā)沖突 和 數據一致性 問題,就需要用到 分布式鎖。
今天給大家介紹一個 .NET 里非常好用的分布式鎖庫 —— DistributedLock。
什么是 DistributedLock
DistributedLock 是一個輕量級、線程安全的 .NET 庫,用來在分布式環(huán)境下實現鎖的功能。支持多種后端存儲,包括:
- Redis
- SQL Server
- PostgreSQL
- MySQL
- MongoDB
- 內存模式(本地鎖)
只需要更換存儲提供程序,就能無縫地在不同的環(huán)境下使用。
基本使用
安裝 NuGet 包
在項目中引入需要的后端依賴,如:
dotnet add package DistributedLock --包含所有實現的元包 dotnet add package DistributedLock.Redis dotnet add package DistributedLock.SqlServer
(Redis 和 SQL Server 是最常見的場景,也可以選擇別的實現)
使用 Redis 分布式鎖
var RedisConnectionString = "localhost:6379,abortConnect=false";
var LockName = "MyResourceLock";
var connection = await ConnectionMultiplexer.ConnectAsync(RedisConnectionString); // uses StackExchange.Redis
var @lock = new RedisDistributedLock(LockName, connection.GetDatabase());
await using (var handle = await @lock.TryAcquireAsync())
{
if (handle != null) { /* I have the lock */ }
}只要使用 Acquire / AcquireAsync 獲取鎖,代碼塊執(zhí)行完畢后會自動釋放,非常優(yōu)雅。
使用 SQL Server 分布式鎖
using Medallion.Threading.SqlServer;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace DistributedLockDemo
{
internal class Program
{
static async Task Main(string[] args)
{
var connectionString = "Server=myServerAddress;Database=Locks;User Id=myUsername;Password=myPassword;";
var lockName = "MyResourceLock";
// 創(chuàng)建分布式鎖對象(不需要 using,因為它不實現 IDisposable)
var sqlLock = new SqlDistributedLock(lockName, connectionString);
// 嘗試獲取鎖,返回的鎖句柄(LockHandle)實現了 IDisposable
using (var lockHandle = sqlLock.TryAcquire(TimeSpan.FromSeconds(30)))
{
if (lockHandle != null) // 判斷是否成功獲取鎖
{
// 持有鎖,執(zhí)行需要同步的代碼
Console.WriteLine("Lock acquired, performing operation...");
// 模擬業(yè)務操作
await Task.Delay(1000); // 建議使用異步延遲而非 Thread.Sleep
}
else
{
Console.WriteLine("Failed to acquire lock within the timeout.");
}
} // 此處會自動釋放鎖(lockHandle.Dispose())
}
}
}在 定時任務(Quartz、Hangfire 等) 場景中,特別適合用來避免多節(jié)點重復執(zhí)行。
依賴注入集成
appsettings.json
{
"ConnectionStrings": {
"SqlServer": "Server=myServerAddress;Database=Locks;User Id=myUsername;Password=myPassword;",
"Redis": "localhost:6379"
}
}DistributedLock 支持依賴注入,適合在項目中使用。
// Startup.cs 或 Program.cs
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("SqlServer");
services.AddSingleton<IDistributedLockProvider>(_ =>
new SqlDistributedSynchronizationProvider(connectionString));
services.AddTransient<SomeService>();
}
// SomeService.cs
public class SomeService
{
private readonly IDistributedLockProvider _lockProvider;
public SomeService(IDistributedLockProvider lockProvider)
{
_lockProvider = lockProvider;
}
public async Task InitializeUserAccountAsync(int id)
{
var @lock = _lockProvider.CreateLock(#34;UserAccount{id}");
await using (await @lock.AcquireAsync())
{
// 執(zhí)行需要同步的操作
Console.WriteLine(#34;Initializing user account {id}...");
await Task.Delay(1000);
}
}
}續(xù)租機制與 RedLock
DistributedLock 的 Redis 實現內置了“看門狗”機制,定期檢查鎖是否仍由當前線程持有,并自動延長鎖的過期時間,避免因業(yè)務處理時間過長導致鎖失效。
DistributedLock 的 Redis 實現支持 RedLock 算法,通過在多個 Redis 節(jié)點上獲取鎖(至少 N/2+1 個節(jié)點)來確保高可靠性。RedLock 適合對一致性要求極高的場景。
適用場景
- 定時任務防重入(保證只有一個節(jié)點執(zhí)行)
- 業(yè)務冪等控制(防止重復提交訂單)
- 緩存擊穿保護(避免多個實例同時回源數據庫)
- 資源互斥訪問(文件寫入、消息處理等)
DistributedLock 是一個簡單易用的分布式鎖庫,支持多種后端,特別適合用在微服務和分布式任務中。
如果你正在開發(fā) 分布式系統(tǒng),強烈建議把它加入到你的工具庫里。
原文鏈接:DistributedLock 實現.Net分布式鎖
到此這篇關于DistributedLock 實現.Net分布式鎖的文章就介紹到這了,更多相關DistributedLock .Net分布式鎖內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
在 asp.net core 的中間件中返回具體的頁面的實現方法
這篇文章主要介紹了在 asp.net core 的中間件中返回具體的頁面的實現方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
在.NET?Core?Web?API中完美配置Swagger文檔的方法
這篇文章主要介紹了在.NET?Core?Web?API中完美配置Swagger文檔的方法,本文通過圖文并茂的形式給大家介紹的非常詳細,感興趣的朋友一起看看吧2024-12-12
MVC使用Spring.Net應用IOC(依賴倒置)學習筆記3
這篇文章主要為大家詳細介紹了MVC使用Spring.Net應用IOC(依賴倒置),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09
Win2008 server + IIS7 設置身份模擬(ASP.NET impersonation)
IIS7 與 IIS 6 相比有了很大的改動,原來在 IIS 6 下可以的設置到了 IIS 7 下有的會發(fā)生變化。身份模擬的配置上,IIS7 和 IIS6有很大不同,網上IIS6的身份模擬的文章比較多,但介紹IIS7的比較少,我把的一些折騰的經驗在這篇博客中寫下來,以供參考2011-10-10

