首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在 ASP.NET Core 中基于 RedLock.net 实现高可用分布式锁方案

在 ASP.NET Core 中基于 RedLock.net 实现高可用分布式锁方案

作者头像
郑子铭
发布2025-07-26 10:41:55
发布2025-07-26 10:41:55
14700
代码可运行
举报
运行总次数:0
代码可运行

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

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

RedLock 算法概述

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

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

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

📌 关键参数

  • expiry:锁的最大存活时间(防止死锁)
  • wait:等待获取锁的最大时间
  • retry:重试间隔时间

项目依赖与安装

所需 NuGet 包

代码语言:javascript
代码运行次数:0
运行
复制
dotnet add package RedLock.net --version 2.3.2
dotnet add package StackExchange.Redis

核心组件设计

DistributedLockService

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

代码语言:javascript
代码运行次数:0
运行
复制
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 DistributedLockService(IConfiguration configuration)
        {
            var redisConnectionString = configuration.GetConnectionString("Redis");
            _redisConnection = ConnectionMultiplexer.Connect(redisConnectionString);

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

        public async Task<bool> ExecuteWithLockAsync(string resource, Func<Task> 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();
        }
    }
}
⚙️ 说明:
  • RedLockMultiplexer 是对 IConnectionMultiplexer 的封装。
  • • 推荐使用至少 3 个独立 Redis 实例 来保证 RedLock 的可靠性。

Startup 配置

DistributedLockService 注册为单例服务:

代码语言:javascript
代码运行次数:0
运行
复制
using Microsoft.Extensions.DependencyInjection;
using DistributedLockSample.Services;

services.AddSingleton<DistributedLockService>();
services.AddControllers();

控制器调用

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

代码语言:javascript
代码运行次数:0
运行
复制
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<IActionResult> 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 中添加 Redis 连接字符串:

代码语言:javascript
代码运行次数:0
运行
复制
{
  "ConnectionStrings": {
    "Redis": "localhost:6379"
  }
}

使用说明

  1. 1. 启动 Redis 实例:确保 Redis 正在运行(推荐使用多实例)。
  2. 2. 注册服务:在 Startup.cs 中注册 DistributedLockService
  3. 3. 调用接口:通过 HTTP 请求触发受锁保护的操作。
  4. 4. 异常处理:未获取到锁时返回 429 Too Many Requests

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RedLock 算法概述
  • 项目依赖与安装
    • 所需 NuGet 包
  • 核心组件设计
    • DistributedLockService
      • ⚙️ 说明:
    • Startup 配置
  • 控制器调用
  • 配置文件说明
  • 使用说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档