RedLock.Net - 基于Redis分布式锁的开源实现
工作中,经常会遇到分布式环境中资源访问冲突问题,比如商城的库存数量处理,或者某个事件的原子性操作,都需要确保某个时间段内只有一个线程在访问或处理资源。
因此现在网上也有很多的分布式锁的解决方案,有数据库、MemCache、ZoopKeeper等等的方式。
这次,我们要学习的是一个基于Redis分布式锁的插件,RedLock.Net。
首先必须要有一个Redis服务来支持此分布式锁,其次就当然是要获取此插件了。
可以从Nuget中获取,也可以直接去Github下载 https://github.com/samcook/RedLock.net。

获取到插件,话不多说上代码。这个是分布式锁的封装类,在需要使用锁的地方直接调用即可。
using RedLock;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net; namespace KingsBlog.Core
{
public class DistributedLockManager
{
private List<RedisLockEndPoint> azureEndPoint;
public DistributedLockManager()
{
azureEndPoint = new List<RedisLockEndPoint>();
azureEndPoint.AddRange(GetEndPoint().Select(o => new RedisLockEndPoint { EndPoint = o.Item1, Password = o.Item2 }));
} /// <summary>
/// 从配置文件获取Redis连接
/// </summary>
/// <returns></returns>
private List<Tuple<EndPoint, string>> GetEndPoint()
{
List<Tuple<EndPoint, string>> result = new List<Tuple<EndPoint, string>>();
var redisParms = RedisCacheBase.ConnectionString.Split(';');
// "127.0.0.1:6379,password=ucs123;127.0.0.1:6378,password=ucs123;"
foreach (var re in redisParms)
{
var re1 = re.Split(',');
var re2 = re1[].Split(':');
var re3 = re1[].Split('=');
result.Add(new Tuple<EndPoint, string>(new DnsEndPoint(re2[], Convert.ToInt16(re2.Length > ? re2[] : "")), re3[]));
}
return result;
} /// <summary>
/// 阻塞式调用,事情最终会被调用(等待时间内)
/// </summary>
/// <param name="resource">锁定资源的标识</param>
/// <param name="expiryTime">锁过期时间</param>
/// <param name="waitTime">等待时间</param>
/// <param name="work"></param>
public bool BlockingWork(string resource, TimeSpan expiryTime, TimeSpan waitTime, Action work)
{
resource = CreateKey(resource);
using (var redisLockFactory = new RedisLockFactory(azureEndPoint))
{
// blocks until acquired or 'wait' timeout
using (var redisLock = redisLockFactory.Create(resource, expiryTime, waitTime, TimeSpan.FromSeconds()))
{
if (redisLock.IsAcquired)
{
work();
return true;
}
}
return false;
}
}
/// <summary>
/// 跳过式调用,如果事情正在被调用,直接跳过
/// </summary>
/// <param name="resource">锁定资源的标识</param>
/// <param name="expiryTime">锁过期时间</param>
/// <param name="work"></param>
public bool OverlappingWork(string resource, TimeSpan expiryTime, Action work)
{
resource = CreateKey(resource);
using (var redisLockFactory = new RedisLockFactory(azureEndPoint))
{
using (var redisLock = redisLockFactory.Create(resource, expiryTime))
{
if (redisLock.IsAcquired)
{
work();
return true;
}
}
return false;
}
} /// <summary>
/// 重新设置键
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private string CreateKey(string key)
{
return string.Join("_", RedisCacheBase.SystemCode, "LOCK", key);
}
}
}
调用示例,简单粗暴
DistributedLockManager lockManager=new DistributedLockManager();
TimeSpan expiryTime = new TimeSpan(,,); bool isWork=lockManager.OverlappingWork("LockName",expiryTime,()=>{
work(); //Do your job
});
if(isWork)
{
//成功执行
}
else
{
//未执行
}
这样就十分简单地实现了基于Redis的分布式锁。
代码很简单,有兴趣的朋友也可以利用反编译软件ILSpy去了解RedLock的实现原理,以下两个截图其实就是RedLock的部分源码:


其它就不多说了,如有疑问,欢迎提出。
RedLock.Net - 基于Redis分布式锁的开源实现的更多相关文章
- c# 基于redis分布式锁
在单进程的系统中,当存在多个线程可以同时改变某个变量(可变共享变量)时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量. 而同步的本质是通过锁来实现的.为了实现多个线程在 ...
- 基于Redis分布式锁(获取锁及解锁)
目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency).可用性( ...
- 基于Redis分布式锁的正确打开方式
分布式锁是在分布式环境下(多个JVM进程)控制多个客户端对某一资源的同步访问的一种实现,与之相对应的是线程锁,线程锁控制的是同一个JVM进程内多个线程之间的同步.分布式锁的一般实现方法是在应用服务器之 ...
- 基于 Redis 分布式锁
1.主流分布式锁实现方案 基于数据库实现分布式锁 基于缓存(redis 等) 基于 Zookeeper 2.根据实现方式分类 : 类 CAS 自旋式分布式锁:询问的方式,类似 java 并发编程中的线 ...
- 基于redis分布式锁实现“秒杀”
转载:http://blog.5ibc.net/p/28883.html 最近在项目中遇到了类似“秒杀”的业务场景,在本篇博客中,我将用一个非常简单的demo,阐述实现所谓“秒杀”的基本思路. 业务场 ...
- 基于redis分布式锁实现“秒杀”(转载)
转载:http://blog.csdn.net/u010359884/article/details/50310387 最近在项目中遇到了类似“秒杀”的业务场景,在本篇博客中,我将用一个非常简单的de ...
- 分布式-技术专区-Redis分布式锁实现-第一步
承接前面一篇Redis分布式锁的原理介绍 https://www.cnblogs.com/liboware/p/11921759.html 我们针对于实现方案进行接下来上篇进行重新的规划和定义以及完善 ...
- Redlock(redis分布式锁)原理分析
Redlock:全名叫做 Redis Distributed Lock;即使用redis实现的分布式锁: 使用场景:多个服务间保证同一时刻同一时间段内同一用户只能有一个请求(防止关键业务出现并发攻击) ...
- Redlock:Redis分布式锁最牛逼的实现
普通实现 说道Redis分布式锁大部分人都会想到:setnx+lua,或者知道set key value px milliseconds nx.后一种方式的核心实现命令如下: - 获取锁(unique ...
随机推荐
- 计算Java对象内存大小
摘要 本文以如何计算Java对象占用内存大小为切入点,在讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型.锁原理 ...
- Docker报错 WARNING: IPv4 forwarding is disabled. Networking will not work.
问题:创建容器的时候报错WARNING: IPv4 forwarding is disabled. Networking will not work. # docker run -it -p 3000 ...
- 下载 youtube 油管的视频
以前也曾经用个工具下过,好像是浏览器插件. 但是到底是什么也记不起来了,删没删除,怎么删除的,全都没有记忆了. 唉,无论多么小的事,只有记到本子或者网络上,才能记得住啊. 所以,这回发现了 youtu ...
- 【Code Tools】Java微基准测试工具JMH之中级篇
一.JMH中的基本概念 1)Mode Mode 表示 JMH 进行 Benchmark 时所使用的模式.通常是测量的维度不同,或是测量的方式不同.目前 JMH 共有四种模式: 1.Throughput ...
- pycharm运行Django项目,提示UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6
确认pycharm编码都是utf-8的情况下,需要修改项目中settings.py 'DIRS': [ ],默认是空,将路径加入即可解决. TEMPLATES = [ { 'BACKEND': 'dj ...
- 【PHP函数】PHP 去掉字符串中的转义符号
PHP字符串中的转义符号 string stripslashes ( string $str ) //去掉字符串中的反斜线字符.若是连续二个反斜线,则去掉一个,留下一个.若只有一个反斜线,就直接去掉.
- C#基于LibUsbDotNet实现USB通信(一)
网上C#USB通信的资料比较少, 基本上都是基于LibUsbDotNet 和 CyUsb, 关于打印机设备的还有一个OPOS. 本篇文章基于LibUsbDotNet. 1. 下载并安装 LibUsbD ...
- 网络传输数据序列化工具Protostuff
一直在物色比较好用的网络传输数据序列化工具,看了诸如marshalling,protobuff等,但是均有一个共同特点,使用起来异常繁杂,有没有比较好用同时性能又不会太差的组件呢?答案当然是有的,那就 ...
- Linux安装mysql5.7
mysql安装排坑,不同版本可能会使用命令不同,这里需要谨慎查阅. 1. 按照需求在mysql官网下载对应linux版本. 2.创建mysql目录,将下载的安装包安装到目录下mkdir /usr/lo ...
- linq中分组查询而且获取每个分组中的第一条记录,数据用于分页绑定
LINQ分组取出第一条数据 Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1" Person3: I ...