在 ASP.NET Core 中基于

360影视 欧美动漫 2025-06-28 13:08 2

摘要:using Microsoft.Extensions.Configuration;using RedLockNet.SERedis;using RedLockNet.SERedis.Configuration;using StackExchange.Redis

在分布式系统中,多个服务实例可能同时访问共享资源,为避免并发问题,需要引入一种可靠的分布式锁机制。

本文介绍如何在 ASP.NET Core 应用中使用 实现基于 Redis 的分布式锁,并结合依赖注入进行封装,以便在业务逻辑中安全地使用。

RedLock 算法概述

RedLock 是由 Redis 作者提出的一种用于构建高可用分布式锁的算法。其核心思想是:

向多个独立的 Redis 节点申请锁,只有超过半数节点成功获取锁时,才认为锁获取成功。

该算法旨在解决单点故障和网络分区带来的不可靠性问题。

关键参数

项目依赖与安装

所需 NuGet 包

dotnet add package RedLock.net --version 2.3.2
dotnet add package StackExchange.Redis 核心组件设计

DistributedLockService

对 RedLock 功能的封装类,负责创建并管理锁的生命周期。

using Microsoft.Extensions.Configuration;
using RedLockNet.SERedis;
using RedLockNet.SERedis.Configuration;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespaceDistributedLockSample.Services
{
publicclassDistributedLockService : IDisposable
{
privatereadonly RedLockFactory _redLockFactory;
privatereadonly IConnectionMultiplexer _redisConnection;

public (IConfiguration configuration)
{
var redisConnectionString = configuration.GetConnectionString("Redis");
_redisConnection = ConnectionMultiplexer.Connect(redisConnectionString);

var redisMultiplexers = new List
{
new RedLockMultiplexer(_redisConnection)
};
_redLockFactory = RedLockFactory.Create(redisMultiplexers);
}

public async Task ExecuteWithLockAsync(string resource, Func action)
{
var expiry = TimeSpan.FromSeconds(30);
var wait = TimeSpan.FromSeconds(10);
var retry = TimeSpan.FromSeconds(1);

awaitusingvar redLock = await _redLockFactory.CreateLockAsync(resource, expiry, wait, retry);

if (redLock.IsAcquired)
{
try
{
await action;
returntrue;
}
catch (Exception ex)
{
Console.WriteLine($"Error executing action: {ex.Message}");
returnfalse;
}
}

Console.WriteLine($"Failed to acquire lock for resource: {resource}");
returnfalse;
}

public void Dispose
{
_redLockFactory?.Dispose;
_redisConnection?.Dispose;
}
}
}

⚙️ 说明:

Startup 配置

将 注册为单例服务: using Microsoft.Extensions.DependencyInjection;
using DistributedLockSample.Services;

services.AddSingleton;
services.AddControllers; 控制器调用

定义一个 API 接口,在执行敏感操作前获取锁:

using Microsoft.AspNetCore.Mvc;
using DistributedLockSample.Services;
using System.Threading.Tasks;

namespaceDistributedLockSample.Controllers
{
[ApiController]
[Route("api/[controller]")]
publicclassExampleController : ControllerBase
{
privatereadonly DistributedLockService _lockService;

public ExampleController(DistributedLockService lockService)
{
_lockService = lockService;
}

[HttpPost("process/{resourceId}")]
public async Task ProcessResource(string resourceId)
{
var result = await _lockService.ExecuteWithLockAsync(
resource: $"resource:{resourceId}",
action: async =>
{
await Task.Delay(1000); // 模拟业务处理
Console.WriteLine($"Processing resource {resourceId} at {DateTime.Now}");
});

if (result)
{
return Ok($"Successfully processed resource {resourceId}");
}

return StatusCode(429, $"Failed to acquire lock for resource {resourceId}");
}
}
} 配置文件说明 在 appsettings.json {
"ConnectionStrings": {
"Redis": "localhost:6379"
}
} 使用说明 1. 启动 Redis 实例 :确保 Redis 正在运行(推荐使用多实例)。 2. 注册服务 :在 Startup.cs 中注册 DistributedLockService 。 3. 调用接口 :通过 HTTP 请求触发受锁保护的操作。 4. 异常处理 :未获取到锁时返回 429 Too Many Requests 。

·············· END ··············

来源:云阳好先生做实事

相关推荐