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 ...
随机推荐
- 大数据Hadoop——初识Hadoop
Hadoop简介 官方网站: http://hadoop.apache.org/ 中文网站: http://hadoop.apache.org/docs/r1.0.4/cn/ Hadoop设计来源 ...
- 关于AMD 、CMD、 commonjs的认识
首先什么是amd.cmd和commonjs.总的来说,这三个玩意就是js的模块规范. 但是,这三者有什么区别呢.... amd规范是应用于浏览器,如requireJS. commonjs规范应用与服务 ...
- Linux之磁盘分区
一.基础知识 1.磁盘分区 磁盘的分区主要分为基本分区(primary partion)和扩充分区(extension partion)两种,基本分区和扩充分区的数目之和不能大于四个.且基本分区可以马 ...
- 如何增加亚马逊listing多个类目节点
流量是电商销售的必要因素,可以说,任何成功的电商平台都离不开流量.亚马逊listing优化做得好,不仅能提高产品的曝光率,还能提升转换率,而好的类目可以吸引大的流量.帮你快速爬升. 首先我们来了解一下 ...
- java,优先队列的用法
像C++语言一样,java中,也有包装好的优先队列类PriorityQueue. 用法如下(模板代码): 工作安排问题: 问题描述:设有n件工作分配给n个人,将工作i分配给第j个人所需的费用为cij. ...
- oracle drop 表后 恢复
1.查看回收站中表 select object_name,original_name,partition_name,type,ts_name,createtime,droptime from recy ...
- 多功能版vue日历控件
下载地址:https://pan.baidu.com/s/1nvpx0tB5cIvvqHuApz_MpQ 之前写了一个简单的vue日历控件:https://www.cnblogs.com/mrzhu/ ...
- There are multiple modules with names that only differ in casing. 黄色warning
There are multiple modules with names that only differ in casing.有多个模块同名仅大小写不同This can lead to unexp ...
- 【css3】画‘百分比圆’
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 服务器安装SSH服务:
强制关闭yum进程: rm -f /var/run/yum.pid 启动SSH: service sshd start 设置开机运行: chkconfig sshd on