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

因此现在网上也有很多的分布式锁的解决方案,有数据库、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. Oracle配置SQL空间操作要点说明

    前面配置PL/SQL直接通过SQL查询SDE空间数据库,网上已有诸多示例, 常见问题如下: ORA-06520: PL/SQL: 加载外部库时出错ORA-06522: Unable to load D ...

  2. 使用JSR-303进行校验

    package com.ieou.comac.module.web.dto.employee; import lombok.Data; import javax.validation.constrai ...

  3. 《图解Java多线程设计模式》读书笔记

    略读中...后面详读的时候,补充经典图片和文字说明

  4. Jmeter 获取系统时间,和对系统时间进行增减时间

    今天做了一个测试,比如发送短信验证码之后的, 验证90s被验证码有效的问题 那如何测试开发的代码,判断了90s内有效呢1. 验证码获取时间距离现在89秒,验证通过2. 验证码获取时间距离现在90秒,验 ...

  5. Js拾忆

    instanceof运算符:他是判断一个构造函数的prototype是否在对象的原型链上查找到 var a = new Array(); console.log(a instanceof Array) ...

  6. samtools 使用简述

    功能如下: 1.View 主要功能讲sam文件转位bam文件. 涉及的参数: -b 输出bam格式..默认是sam文件 -h 输出的sam文件带header..默认不带 -H 仅仅输出header - ...

  7. PYTHON -- 基础3

    1.数据类型 1.int 类型 用于计算 1.1 bit_length() 转换为2进制的最小位置 有效的 i = 5 print(i.bit_length()) i 二进制 i.bit_length ...

  8. Confluence 6 从 WIKI 标记整合到基于 XHTML 的存储格式

    如果你现在正在将 Confluence 从一个老的版本升级到 Confluence 4.0 或者更新的版本 (例如从 Confluence 3.5.x 或者更老的版本),在升级的过程中一个内容整合过程 ...

  9. fetch与XHR的区别与优势

    Fetch API更加现代 XHR 和 Fetch API 最显著的区别就是调用方式不同.这一点大家应该都知道吧. 举个例子,下面两端代码完成的是同一功能: // 用 XHR 发起一个GET请求 va ...

  10. docker 安装elasticSearch7.0.0

    一.执行命令:docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-n ...