⒈简介

  RedLock 分布式锁算法由 Redis 的作者提出,大部分语言都有对应的实现,查看,RedLock.net 是 RedLock 分布式锁算法的 .NET 版实现,用来解决分布式下的并发问题。

  RedLock 的思想是使用多台 Redis Master ,节点之间完全独立,节点间不需要进行数据同步,因为 Master-Slave 架构一旦 Master 发生故障时数据没有复制到 Slave,被选为 Master 的 Slave 就丢掉了锁,另一个客户端就可以再次拿到锁。

  锁通过 setNX(原子操作) 命令设置,在有效时间内当获得锁的数量大于 (n/2+1) 代表成功,失败后需要向所有节点发送释放锁的消息。

  获取锁:

 SET resource_name my_random_value NX PX 30000

  释放锁:

 if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end

⒉使用

  1.创建 .NETCore API 项目

  2.Nuget 安装 RedLock.net

 Install-Package RedLock.net

  3.appsettings.json 添加 redis 配置

 {
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"RedisUrls": [
"127.0.0.1:6379",
"192.168.214.128:6379"
]
}

  4.添加 ProductService.cs,模拟商品购买

 // 有10个商品库存,如果同时启动多个API服务进行测试,这里改成存数据库或其他方式
private static int stockCount = ;
public async Task<bool> BuyAsync()
{
// 模拟执行的逻辑代码花费的时间
await Task.Delay(new Random().Next(, ));
if (stockCount > )
{
stockCount--;
return true;
}
return false;
}

  5.修改 Startup.cs ,创建 RedLockFactory

    1.定义RedLockFactory属性

         private RedLockFactory lockFactory
{
get
{
var redisUrls = Configuration.GetSection("RedisUrls").GetChildren().Select(s => s.Value).ToArray();
if(redisUrls.Length <= )
{
throw new ArgumentException("RedisUrl 不能为空");
}
var endPoints = new List<RedLockEndPoint>();
foreach (var item in redisUrls)
{
var arr = item.Split(":");
endPoints.Add(new DnsEndPoint(arr[], Convert.ToInt32(arr[])));
}
return RedLockFactory.Create(endPoints);
}
}

    2.在 ConfigureServices 注入 IDistributedLockFactory:

         // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton(typeof(IDistributedLockFactory), lockFactory);
services.AddScoped(typeof(ProductService));
}

    3.修改 Configure,应用程序结束时释放 lockFactory

         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMvc(); lifetime.ApplicationStopping.Register(() =>
{
lockFactory.Dispose();
}); }

  6.在 Controller 添加方法 DistributedLockTest

 private readonly IDistributedLockFactory _distributedLockFactory;
private readonly ProductService _productService; public HomeController(IDistributedLockFactory distributedLockFactory,
ProductService productService)
{
_distributedLockFactory = distributedLockFactory;
_productService = productService;
} [HttpGet]
public async Task<bool> DistributedLockTest()
{
var productId = "id";
// resource 锁定的对象
// expiryTime 锁定过期时间,锁区域内的逻辑执行如果超过过期时间,锁将被释放
// waitTime 等待时间,相同的 resource 如果当前的锁被其他线程占用,最多等待时间
// retryTime 等待时间内,多久尝试获取一次
using (var redLock = await _distributedLockFactory.CreateLockAsync(productId, TimeSpan.FromSeconds(), TimeSpan.FromSeconds(), TimeSpan.FromMilliseconds()))
{
if (redLock.IsAcquired)
{
var result = await _productService.BuyAsync();
return result;
}
else
{
Console.WriteLine($"获取锁失败:{DateTime.Now}");
}
}
return false;
}

  在文章RedLock 实现分布式锁基础之上修改部分代码编写。

  

  

在.Net中使用RedLock实现分布式锁的更多相关文章

  1. Redis中是如何实现分布式锁的?

    分布式锁常见的三种实现方式: 数据库乐观锁: 基于Redis的分布式锁: 基于ZooKeeper的分布式锁. 本地面试考点是,你对Redis使用熟悉吗?Redis中是如何实现分布式锁的. 要点 Red ...

  2. springboot 中单机 redis 实现分布式锁

    在微服务中经常需要使用分布式锁,来执行一些任务.例如定期删除过期数据,在多个服务中只需要一个去执行即可. 以下说明非严格意义的分布式锁,因为 redis 实现严格意义的分布式锁还是比较复杂的,对于日常 ...

  3. Springboot中使用Redisson实现分布式锁

    1. 概述 老话说的好:便宜没好货,有价值的商品,即使再贵,也有人会买. 言归正传,今天继续讨论有关"锁"的话题,synchronized 和 ReentrantLock 大家应该 ...

  4. Spring Cloud分布式微服务系统中利用redssion实现分布式锁

    在非分布式系统中要实现锁的机制很简单,利用java.util.concurrent.locks包下的Lock和关键字synchronized都可以实现.但是在分布式系统中,如何实现各个单独的微服务需要 ...

  5. RedLock 实现分布式锁

    J并发是程序开发中不可避免的问题,根据系统面向用户.功能场景的不同,并发的重视程度会有不同.从程序的角度来说,并发意味着相同的时间点执行了相同的代码,而有些情况是不被允许的,比如:转账.抢购占库存等, ...

  6. 分布式锁之三:Redlock实现分布式锁

    之前写过一篇文章<如何在springcloud分布式系统中实现分布式锁?>,由于自己仅仅是阅读了相关的书籍,和查阅了相关的资料,就认为那样的是可行的.那篇文章实现的大概思路是用setNx命 ...

  7. 如何用Redlock实现分布式锁

    转载请标明出处: http://blog.csdn.net/forezp/article/details/70305336 本文出自方志朋的博客 之前写过一篇文章<如何在springcloud分 ...

  8. spring-boot 中实现标准 redis 分布式锁

    一,前言 redis 现在已经成为系统缓存的必备组件,针对缓存读取更新操作,通常我们希望当缓存过期之后能够只有一个请求去更新缓存,其它请求依然使用旧的数据.这就需要用到锁,因为应用服务多数以集群方式部 ...

  9. .Net 下基于Redlock redis 分布式锁实现

    Redlock-cs (C#/.NET implementation). RedLock.net (C#/.NET implementation). Includes async and lock e ...

随机推荐

  1. MessagePack Java Jackson 在不关闭输入流(input stream)的情况下反序列化多变量

    com.fasterxml.jackson.databind.ObjectMapper 在读取输入流变量的时候默认的将会关闭输入流. 如果你不希望关闭输入流,你可以设置 JsonParser.Feat ...

  2. 微信小程序_(组件)scroll-view可滚动视图

    微信小程序scroll-view组件官方文档 传送门 提前准备:使用<view>组件制作五条撑满的横向区域 <!--index.wxml--> Cynical丶Gary < ...

  3. python3 格式化输出,字符串操作,模块,列表,元组

    初识python,在网上看了老男孩的视频,建立一个博客将自己所学的python知识记录下来. input加密,用于输入密码的阶段. import getpass user = input(" ...

  4. import 和 require 的 区别

    node编程中最重要的思想就是模块化,import和require都是被模块化所使用. 遵循规范 require 是 AMD规范引入方式 import是es6的一个语法标准,如果要兼容浏览器的话必须转 ...

  5. 最少步数&P1443 马的遍历

      1330:[例8.3]最少步数 s数组:记录(1,1)到达每一点需要的最少步数 s[1][1]自然为 0,其余初始化为 -1 que数组:que[#][1] 表示(1,1)可到达点的 x 坐标 q ...

  6. java高级之Io流

    1.1,什么是io流? 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作 ...

  7. 六十:Flask.Cookie之flask设置cookie的有效域名

    设置cookie有效域名cookie默认只能在主域名下使用,如果要在子域名下使用,则应该给set_cookie设置属性domain='.主域名',此时,此cookie在此主域名下的所有子域名均有效 f ...

  8. mac 安装photoshop + 破解

    项目开发中毫无疑问会用到图片,一般情况都是UI将图片切好的,只是,有时候项目中少了一张图片或者是改变图片的尺寸之类的问题,这里我们就不需要每次都找UI要图片了,作为程序员这些基础工具的使用,咱们还是要 ...

  9. C基础知识(14):命令行参数

    命令行参数是使用main()函数参数来处理的,其中,argc是指传入参数的个数,argv[]是一个指针数组,指向传递给程序的每个参数. 应当指出的是,argv[0]存储程序的名称,argv[1]是一个 ...

  10. Kubernetes中的PV和PVC

    K8S引入了一组叫作Persistent Volume Claim(PVC)和Persistent Volume(PV)的API对象,大大降低了用户声明和使用持久化Volume的门槛.在Pod的Vol ...