⒈简介

  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. Java web 公文流转系统 完成结果

    河北金力集团公文流转系统 1.项目需求: 河北金力集团是我省机械加工的龙头企业,主要从事矿山机械制造及各种机械零部件加工.企业有3个厂区,主厂区位于省高新技术开发区,3个分厂分别在保定.邢台和唐山.为 ...

  2. [JZOJ5400]:Repulsed(贪心+树形DP)

    题目描述 小$w$心里的火焰就要被熄灭了. 简便起见,假设小$w$的内心是一棵$n-1$条边,$n$个节点的树. 现在你要在每个节点里放一些个灭火器,每个节点可以放任意多个. 接下来每个节点都要被分配 ...

  3. BZOJ1706奶牛接力跑

    这个东西思路还是不错的. 解法就是把矩阵幂的加法改成取min,乘法改成加法就好,和floyed是一样的.这样的话,矩阵操作一次就相当于松弛了一次最短路. 建矩阵的过程也比较简单,可以离散化,当然下面有 ...

  4. mysql 数据库备份 -- (定时任务)

    场景: 我们经常需要对数据库备份 方式一:mysql 数据备份方式 在linux 备份方式  通常采用 mysqldump -uroot -ppassword  --database 数据库名 > ...

  5. window 下要运行php,需要编辑php环境变量

    参考:https://blog.csdn.net/zhezhebie/article/details/72765262

  6. 微服务一键启动脚本shell没有环境变量的

    #!/bin/bash#######################################################export JAVA_HOME=/root/data/app/jd ...

  7. yum 时一直停在Determining fastest mirrors 界面

    [root@fanyk ~]# yum redis Loaded plugins: fastestmirror Determining fastest mirrors 在yum makecache时, ...

  8. html添加注释怎么弄?

    HTML 注释: <!--这是一段注释.注释不会在浏览器中显示.--> 这是一段普通的段落. 快捷键: 我用的是 Notpad++ 添加行注释 Ctrl+K 取消行注释 Ctrl+Shif ...

  9. css样式重置表

    /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) */ html, ...

  10. Android百分比支持布局库的使用和源码分析

    Android-percent-support这个库 描述下这个support-lib. 这个库提供了: 两种布局供大家使用: PercentRelativeLayout.PercentFrameLa ...