在.Net中使用RedLock实现分布式锁
⒈简介
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实现分布式锁的更多相关文章
- Redis中是如何实现分布式锁的?
分布式锁常见的三种实现方式: 数据库乐观锁: 基于Redis的分布式锁: 基于ZooKeeper的分布式锁. 本地面试考点是,你对Redis使用熟悉吗?Redis中是如何实现分布式锁的. 要点 Red ...
- springboot 中单机 redis 实现分布式锁
在微服务中经常需要使用分布式锁,来执行一些任务.例如定期删除过期数据,在多个服务中只需要一个去执行即可. 以下说明非严格意义的分布式锁,因为 redis 实现严格意义的分布式锁还是比较复杂的,对于日常 ...
- Springboot中使用Redisson实现分布式锁
1. 概述 老话说的好:便宜没好货,有价值的商品,即使再贵,也有人会买. 言归正传,今天继续讨论有关"锁"的话题,synchronized 和 ReentrantLock 大家应该 ...
- Spring Cloud分布式微服务系统中利用redssion实现分布式锁
在非分布式系统中要实现锁的机制很简单,利用java.util.concurrent.locks包下的Lock和关键字synchronized都可以实现.但是在分布式系统中,如何实现各个单独的微服务需要 ...
- RedLock 实现分布式锁
J并发是程序开发中不可避免的问题,根据系统面向用户.功能场景的不同,并发的重视程度会有不同.从程序的角度来说,并发意味着相同的时间点执行了相同的代码,而有些情况是不被允许的,比如:转账.抢购占库存等, ...
- 分布式锁之三:Redlock实现分布式锁
之前写过一篇文章<如何在springcloud分布式系统中实现分布式锁?>,由于自己仅仅是阅读了相关的书籍,和查阅了相关的资料,就认为那样的是可行的.那篇文章实现的大概思路是用setNx命 ...
- 如何用Redlock实现分布式锁
转载请标明出处: http://blog.csdn.net/forezp/article/details/70305336 本文出自方志朋的博客 之前写过一篇文章<如何在springcloud分 ...
- spring-boot 中实现标准 redis 分布式锁
一,前言 redis 现在已经成为系统缓存的必备组件,针对缓存读取更新操作,通常我们希望当缓存过期之后能够只有一个请求去更新缓存,其它请求依然使用旧的数据.这就需要用到锁,因为应用服务多数以集群方式部 ...
- .Net 下基于Redlock redis 分布式锁实现
Redlock-cs (C#/.NET implementation). RedLock.net (C#/.NET implementation). Includes async and lock e ...
随机推荐
- 洛谷 P1800 software_NOI导刊2010提高(06)(二分答案+DP检验)
P1800 software_NOI导刊2010提高(06) 标签 二分答案 难度 普及/提高- 题目描述 一个软件开发公司同时要开发两个软件,并且要同时交付给用户,现在公司为了尽快完成这一任务,将每 ...
- svn版本更新
1.查看当前版本:svn --version 2.配置svn yum源 tee /etc/yum.repos.d/wandisco-svn.repo <<-'EOF' [WandiscoS ...
- 文件操作(stat函数)
stat函数可以获取文件信息 /*** stat.c ***/ #include<stdio.h> #include<string.h> #include<sys/sta ...
- 使用python 将地址链接变成二维码
import os from MyQR import myqr myqr.run( words='https://sz.ke.com/?utm_source=baidu&utm_medium= ...
- js判断是否是app,及版本号
判断是否是android,ios,qq,wetchat export const Config = {}; Config.ua = navigator.userAgent.toLowerCase(); ...
- TypeScript----数据类型
TypeScript 简介 TypeScript 由 Microsoft开发和维护的一种开源编程语言.它支持 JavaScript 的所有语法和语义,同时通过作为 ECMAScript 的超集来提供一 ...
- [题解] [bzoj2622] 深入虎穴
题解 题解 考虑到正着跑不好想, 我们尝试反向跑 以每个终点作为起点, 维护每个点的最小值和次小值(最小的被老虎ban掉了) 转移的时候用当前点的次小值去更新其所连的点的最小值和次小值 由于最小的次小 ...
- Linux 变量 $$ $! $? $- $# $* $@ $0 $n
[参考文章]:linux中shell变量$#,$@,$0,$1,$2的含义解释 1. 变量说明 1.1 $$ Shell本身的PID(ProcessID) 1.2 $! Shell最后运行的后台Pro ...
- Socket——实现一个简单的静态网页服务器
整体结构就是使用ServerSocket监听一个地址,当有接受到请求之后,解析请求中的资源路径.服务器资源路径存放在项目下的一个目录中,服务器会到这个目录中根据请求的路径去寻找相应的资源.如果找到了则 ...
- Python中函数的使用
函数让代码的编写,阅读,测试和修改都变得更容易,提高代码的复用性,python中使用def关键字定义函数 如下代码在python3.7.3的Genay开发工具中编写测试通过. 一.简单函数定义及调用 ...