工作中,经常会遇到分布式环境中资源访问冲突问题,比如商城的库存数量处理,或者某个事件的原子性操作,都需要确保某个时间段内只有一个线程在访问或处理资源。

因此现在网上也有很多的分布式锁的解决方案,有数据库、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分布式锁的开源实现的更多相关文章

  1. c# 基于redis分布式锁

    在单进程的系统中,当存在多个线程可以同时改变某个变量(可变共享变量)时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量. 而同步的本质是通过锁来实现的.为了实现多个线程在 ...

  2. 基于Redis分布式锁(获取锁及解锁)

    目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency).可用性( ...

  3. 基于Redis分布式锁的正确打开方式

    分布式锁是在分布式环境下(多个JVM进程)控制多个客户端对某一资源的同步访问的一种实现,与之相对应的是线程锁,线程锁控制的是同一个JVM进程内多个线程之间的同步.分布式锁的一般实现方法是在应用服务器之 ...

  4. 基于 Redis 分布式锁

    1.主流分布式锁实现方案 基于数据库实现分布式锁 基于缓存(redis 等) 基于 Zookeeper 2.根据实现方式分类 : 类 CAS 自旋式分布式锁:询问的方式,类似 java 并发编程中的线 ...

  5. 基于redis分布式锁实现“秒杀”

    转载:http://blog.5ibc.net/p/28883.html 最近在项目中遇到了类似“秒杀”的业务场景,在本篇博客中,我将用一个非常简单的demo,阐述实现所谓“秒杀”的基本思路. 业务场 ...

  6. 基于redis分布式锁实现“秒杀”(转载)

    转载:http://blog.csdn.net/u010359884/article/details/50310387 最近在项目中遇到了类似“秒杀”的业务场景,在本篇博客中,我将用一个非常简单的de ...

  7. 分布式-技术专区-Redis分布式锁实现-第一步

    承接前面一篇Redis分布式锁的原理介绍 https://www.cnblogs.com/liboware/p/11921759.html 我们针对于实现方案进行接下来上篇进行重新的规划和定义以及完善 ...

  8. Redlock(redis分布式锁)原理分析

    Redlock:全名叫做 Redis Distributed Lock;即使用redis实现的分布式锁: 使用场景:多个服务间保证同一时刻同一时间段内同一用户只能有一个请求(防止关键业务出现并发攻击) ...

  9. Redlock:Redis分布式锁最牛逼的实现

    普通实现 说道Redis分布式锁大部分人都会想到:setnx+lua,或者知道set key value px milliseconds nx.后一种方式的核心实现命令如下: - 获取锁(unique ...

随机推荐

  1. win7 / mysql-8.0.11-winx64 安装的测坑步骤

    虚惊一场,主要问题是 Navicat Premium 连接 mysql8  Client does not support authentication . 1.  下载 官网下载压缩包: mysql ...

  2. selenium java maven testNg环境搭建

    maven获取jar的xml地址:http://mvnrepository.com 步骤一安装jdk(略) 步骤二 安装eclipse(略) 步骤三 安装testNG 步骤四 maven安装 步骤三 ...

  3. VirtualBox中CentOS7.2 网络配置(固定IP+联网)

    一.前言 用虚拟机装Linux系统时,经常会出现一些问题.比如:从主机到虚拟机之间网络不通:虚拟机中无法联网:虚拟机中的IP地址不固定.为了解决这些问题,我曾花了不少时间.在此,记下填坑方法. 二.环 ...

  4. Xshell利用lrzsz工具上传下载

    直接安装这个lrzsz工具 yum install lrzsz 上传 rz 下载 sz

  5. 2019.3.16数据结构考试(Problem 1. rotinv)(循环逆序对)

    Problem 1. rotinvInput file: rotinv.inOutput file: rotinv.outTime limit: 2 secondsMemory limit: 256 ...

  6. Element-ui框架checkbox复选框回显

    先看下效果是不是你需要的..... 然后废话不多说,上代码,希望能够帮助到你... <template> <div class=''> <el-form label-wi ...

  7. MongDB 批量更新

    最近公司在使用mongodb.  批量更新的语句为: db.table.update(  {'wo': {$in: [ "123", "456"]}}, {$s ...

  8. Django_URL

    视图函数介绍 视图一般都写在app的views中,并且视图的第一个参数永远都是request(HttpRequest)对象.这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等.再视图中 ...

  9. Nginx配置文件及模块解析

    一.Nginx是什么? Nginx是一个基于c语言开发的高性能http服务器及反向代理服务器.由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu.内 ...

  10. python--日志模块

    一.logging模块就是python里面用来操作日志的模块,logging模块中主要有4个类,分别负责不同的工作 1. Logger 记录器,暴露了应用程序代码能直接使用的接口:简单点说就是一个创建 ...