⒈简介

  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. OI路上 day -9

    /* 嗯还有9天. 就只有9天了. 啊还剩9天吖! 多年后 我可能还会记得 那些年,我们学过的算法. 多年后 我可能会对别人说 我学过OI我喜欢OI并一直热爱着它. 9天后 我可能再也不会来到这个地方 ...

  2. 【CUDA 基础】0.0 腾讯云CUDA环境搭建

    title: [CUDA 基础]0.0 腾讯云CUDA环境搭建 categories: CUDA Freshman tags: CUDA 环境搭建 toc: true date: 2018-02-13 ...

  3. ETL工具-KETTLE教程专栏1----术语和定义

    1-资源库 资源库是用来保存转换任务的,用户通过图形界面创建的的转换任务可以保存在资源库中.        资源库可以使多用户共享转换任务,转换任务在资源库中是以文件夹形式分组管理的,用户可以自定义文 ...

  4. Python3学习笔记(十八):文件上传和下载

    文件上传 以人人网上传头像为例,用Fiddler抓取的上传头像接口报文如下 上传头像图片代码: import requests upload_url = 'http://upload.renren.c ...

  5. 突破大文件上传 和内网ip的端口转发

    php上传大于2M文件的解决方法 2016年12月11日 :: katelyn9 阅读数 php上传大于2M文件的解决方法 如上传一个文件大于2m往往是上传不成功的解决方法: php.ini里查找 查 ...

  6. TCP输出 之 tcp_write_xmit

    概述 tcp_write_xmit函数完成对待发送数据的分段发送,过程中会遍历发送队列,进行窗口检查,需要TSO分段则分段,然后调用tcp_transmit_skb发送数据段: 源码分析 static ...

  7. python基础_0623

    命名的规则: project name    package name    python file name 1. 不能以数字开头,不能使用中文 2. 不能使用关键字 3. 英文    字母    ...

  8. LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)

    题目描述 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数. 示例 1: 输入: roo ...

  9. 百度地图java 判断当前位置是否在多边形区域内

    package com.haiyisoft.cAssistant.adapter.hessian; import java.awt.geom.Point2D;import java.util.Arra ...

  10. Sql语法树示例 select username, ismale from userinfo where age > 20 and level > 5 and 1 = 1

    select username, ismale from userinfo where age > 20 and level > 5 and 1 = 1 --END-2019年9月5日17 ...