亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

.NET?Core使用Redis實(shí)現(xiàn)創(chuàng)建分布式鎖

 更新時(shí)間:2025年01月19日 08:31:09   作者:代碼拾光  
分布式鎖一般用于確保在分布式系統(tǒng)中,同一時(shí)間只有一個(gè)進(jìn)程可以執(zhí)行某段代碼,本文將通過(guò).NET?Core使用Redis實(shí)現(xiàn)創(chuàng)建分布式鎖,感興趣的可以了解下

在 .NET Core WebApi 中使用 Redis 創(chuàng)建分布式鎖可以通過(guò) StackExchange.Redis 庫(kù)來(lái)實(shí)現(xiàn)。分布式鎖用于確保在分布式系統(tǒng)中,同一時(shí)間只有一個(gè)進(jìn)程可以執(zhí)行某段代碼。

1. 場(chǎng)景描述

在支付系統(tǒng)中,可能會(huì)出現(xiàn)以下并發(fā)問(wèn)題:

  • 用戶(hù)同時(shí)發(fā)起多次支付請(qǐng)求,導(dǎo)致重復(fù)扣款。
  • 多個(gè)請(qǐng)求同時(shí)處理同一個(gè)訂單,導(dǎo)致數(shù)據(jù)不一致。

通過(guò)分布式鎖,可以確保同一時(shí)間只有一個(gè)請(qǐng)求能夠執(zhí)行關(guān)鍵操作(如扣款)。

2. 實(shí)現(xiàn)步驟

2.1 安裝 StackExchange.Redis 包

首先,安裝 Redis 客戶(hù)端庫(kù):

dotnet add package StackExchange.Redis

2.2 配置 Redis 連接

在 appsettings.json 中添加 Redis 連接字符串:

{
  "ConnectionStrings": {
    "Redis": "localhost:6379"
  }
}

2.3 創(chuàng)建分布式鎖工具類(lèi)

創(chuàng)建一個(gè)工具類(lèi)來(lái)封裝 Redis 分布式鎖的邏輯:

using StackExchange.Redis;
using System;
using System.Threading.Tasks;

public class RedisDistributedLock
{
    private readonly IDatabase _redisDatabase;
    private readonly string _lockKey;
    private readonly string _lockValue;
    private readonly TimeSpan _expiry;

    public RedisDistributedLock(IDatabase redisDatabase, string lockKey, string lockValue, TimeSpan expiry)
    {
        _redisDatabase = redisDatabase;
        _lockKey = lockKey;
        _lockValue = lockValue;
        _expiry = expiry;
    }

    public async Task<bool> AcquireLockAsync()
    {
        // 嘗試設(shè)置鎖,僅當(dāng)鍵不存在時(shí)才成功
        return await _redisDatabase.StringSetAsync(_lockKey, _lockValue, _expiry, When.NotExists);
    }

    public async Task ReleaseLockAsync()
    {
        // 使用 Lua 腳本確保只有鎖的持有者才能釋放鎖
        var luaScript = @"
            if redis.call('GET', KEYS[1]) == ARGV[1] then
                return redis.call('DEL', KEYS[1])
            else
                return 0
            end";

        await _redisDatabase.ScriptEvaluateAsync(luaScript, new RedisKey[] { _lockKey }, new RedisValue[] { _lockValue });
    }
}

2.4 在 Web API 中使用分布式鎖

在 Web API 的控制器中使用分布式鎖來(lái)確保支付操作的原子性。

2.4.1 注冊(cè) Redis 服務(wù)

在 Startup.cs 或 Program.cs 中注冊(cè) Redis 服務(wù):

// 添加 Redis 服務(wù)
builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
ConnectionMultiplexer.Connect(builder.Configuration.GetConnectionString("Redis")));

2.4.2 創(chuàng)建支付控制器

在 Controllers 文件夾中創(chuàng)建一個(gè) PaymentController,并在其中使用分布式鎖:

using Microsoft.AspNetCore.Mvc;
using StackExchange.Redis;
using System;
using System.Threading.Tasks;

    [ApiController]
    [Route("api/[controller]")]
    public class PaymentController : ControllerBase
    {
        private readonly IDatabase _redisDatabase;

        public PaymentController(IConnectionMultiplexer redis)
        {
            _redisDatabase = redis.GetDatabase();
        }

        [HttpPost("pay")]
        public async Task<IActionResult> ProcessPayment([FromBody] PaymentRequest request)
        {
            // 創(chuàng)建分布式鎖
            var lockKey = $"PaymentLock:{request.OrderId}"; // 鎖的鍵,基于訂單 ID
            var lockValue = Guid.NewGuid().ToString(); // 鎖的值,確保唯一性
            var expiry = TimeSpan.FromSeconds(10); // 鎖的過(guò)期時(shí)間

            var distributedLock = new RedisDistributedLock(_redisDatabase, lockKey, lockValue, expiry);

            try
            {
                // 嘗試獲取鎖
                if (await distributedLock.AcquireLockAsync())
                {
                    Console.WriteLine("已獲取鎖,正在處理付款...");

                    // 模擬支付處理
                    bool paymentSuccess = await ProcessPaymentAsync(request.UserId, request.OrderId, request.Amount);

                    if (paymentSuccess)
                    {
                        return Ok(new { Message = "付款成功!" });
                    }
                    else
                    {
                        return BadRequest(new { Message = "付款失敗!" });
                    }
                }
                else
                {
                    return Conflict(new { Message = "正在處理此訂單的另一個(gè)付款請(qǐng)求..." });
                }
            }
            finally
            {
                // 釋放鎖
                await distributedLock.ReleaseLockAsync();
            }
        }

      
    }

3. 代碼說(shuō)明

3.1 分布式鎖的實(shí)現(xiàn)

AcquireLockAsync: 使用 Redis 的 SET key value NX EX 命令嘗試獲取鎖。NX 表示僅在鍵不存在時(shí)設(shè)置,`EX 設(shè)置鍵的過(guò)期時(shí)間。

ReleaseLockAsync: 使用 Lua 腳本確保只有鎖的持有者才能釋放鎖,避免誤刪其他請(qǐng)求的鎖。

3.2 支付控制器的使用

鎖的鍵: 使用訂單 ID 作為鎖的鍵(如 PaymentLock:202501061410455506968463210),確保同一訂單的支付請(qǐng)求串行化。

鎖的值: 使用 GUID 作為鎖的值,確保鎖的唯一性。

鎖的過(guò)期時(shí)間: 設(shè)置合理的過(guò)期時(shí)間(如 10 秒),防止鎖被長(zhǎng)時(shí)間占用。

3.3 支付處理邏輯

ProcessPaymentAsync: 模擬支付處理邏輯,包括調(diào)用支付網(wǎng)關(guān)、扣減余額等操作。

4. 測(cè)試 API

4.1 啟動(dòng) Web API

運(yùn)行項(xiàng)目,啟動(dòng) Web API。

4.2 發(fā)送支付請(qǐng)求

使用工具(如 Postman 或 curl)發(fā)送支付請(qǐng)求:

POST /api/payment/pay
Content-Type: application/json

{
    "userId": "9527",
    "orderId": "202501061410455506968463210"
    }

4.3 測(cè)試并發(fā)場(chǎng)景

同時(shí)發(fā)送多個(gè)相同的支付請(qǐng)求,觀察是否只有一個(gè)請(qǐng)求能夠成功獲取鎖并處理支付。

5. 注意事項(xiàng)

鎖的粒度:

  • 鎖的粒度要適中。如果鎖的粒度過(guò)大(如全局鎖),可能導(dǎo)致性能問(wèn)題;如果粒度過(guò)小,可能增加復(fù)雜性。
  • 在支付系統(tǒng)中,通常以訂單 ID 或用戶(hù) ID 作為鎖的粒度。

鎖的過(guò)期時(shí)間:

  • 設(shè)置合理的過(guò)期時(shí)間,避免鎖被長(zhǎng)時(shí)間占用導(dǎo)致死鎖。
  • 如果業(yè)務(wù)邏輯執(zhí)行時(shí)間較長(zhǎng),可以動(dòng)態(tài)延長(zhǎng)鎖的過(guò)期時(shí)間。

鎖的可靠性:

Redis 需要高可用,否則可能導(dǎo)致鎖失效。可以使用 Redis 集群或 Redlock 算法提高可靠性。

異常處理:

確保鎖的釋放操作放在 finally 塊中,避免因異常導(dǎo)致鎖無(wú)法釋放。

冪等性:

支付系統(tǒng)需要支持冪等性,即使多次請(qǐng)求,也只會(huì)產(chǎn)生一次扣款。

6. 總結(jié)

在 .NET Core Web API 中使用 Redis 創(chuàng)建分布式鎖,可以帶來(lái)以下好處:

  • 解決并發(fā)問(wèn)題,確保數(shù)據(jù)一致性。
  • 提高系統(tǒng)的可靠性和性能。
  • 簡(jiǎn)化代碼邏輯,降低開(kāi)發(fā)復(fù)雜度。
  • 支持高并發(fā)、分布式環(huán)境和高可用需求。

通過(guò)合理使用 Redis 分布式鎖,可以構(gòu)建高可靠、高性能的分布式系統(tǒng),滿(mǎn)足復(fù)雜的業(yè)務(wù)需求。

到此這篇關(guān)于.NET Core使用Redis實(shí)現(xiàn)創(chuàng)建分布式鎖的文章就介紹到這了,更多相關(guān).NET Redis創(chuàng)建分布式鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論