Redis用作分布式锁
Redis用作分布式锁使用的业务逻辑
。。。
。。。
简单的使用案例如下(商品秒杀应用场景)
准备工作:
下面商品秒杀应用场景案例演示的前提是Redis已经安装,并可以使用。
本作者从下载地址:https://download.csdn.net/download/LongtengGensSupreme/12157626下载redis包解压到本地文件目录:E:\Source\redisfile\Redis-x64-3.2.100,如下图所示
为了方便启动,我们在该目录下新建一个 startredis.bat 的文件,
然后将以下内容写入文件:redis-server redis.windows.conf
这个命令其实就是在调用 redis-server.exe 命令来读取 redis.window.conf 的内容,
双击刚才创建好的 startredis.bat 文件,就能成功的看到 Redis 启动,如下图所示:
redis-server启动之后放着就可以了。
Redis 自带的一个客户端工具,它可以用来连接到我们当前的 Redis 服务器,点击同一个文件夹下的 redis-cli.exe 文件,启动客户端,如下图
redis-cli客户端启动成功,如下图所示
我们做以下测试:在客户端dos界面输入 set key1 value1,回车,可以看到客户端显示:
在输入 get key1 回车,客户端显示:
通过上述工作,我们便在 Windows 的环境下安装好了Redis,我们的准备工作已完成。下面添加简单的使用案例(商品秒杀应用场景) 如下:
1、使用Visual studio 2019 Enterprise 创建一个控制台项目 ConsoleTestRedis,选择项目右键,点击NuGet包管理器 ,搜索并添加 StackExchange.Redis
2、添加客户端请求类 Client,商品秒杀 ProductKill ,Redis分布式锁 RedisLock 类
客户端请求类 Client代码如下:
using System.Threading; namespace ConsoleTestRedis { /// <summary> /// 客户端请求 /// </summary> public class Client { public void CleitRequest() { ProductKill productKill = new ProductKill(); for (int i = 0; i < 20; i++) { new Thread(() => { productKill.KillProduct(); }).Start(); } } } }
商品秒杀 ProductKill代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleTestRedis { /// <summary> /// 商品秒杀 /// </summary> public class ProductKill { /// <summary> /// 库存数量 /// </summary> public int repositoryNumber = 10; /// <summary> /// 获取库存的数量 /// </summary> /// <returns></returns> public int GetRepositoryNumber() { return repositoryNumber; } /// <summary> /// 扣减库存数量 /// </summary> public void SetRepositoryNumber() { repositoryNumber--; ; } /// <summary> /// 商品秒杀 /// </summary> public void KillProduct() { //使用Redis分布式锁RedisLock RedisLock redisLock = new RedisLock(); redisLock.Lock(); var restory = GetRepositoryNumber(); if (restory == 0) { Console.WriteLine($" {Thread.CurrentThread.ManagedThreadId} 不好意思获取失败!商品库存数量:{repositoryNumber}"); redisLock.UnLock(); return; } Console.WriteLine($"恭喜 {Thread.CurrentThread.ManagedThreadId} 获取秒杀商品成功!商品库存数量:{repositoryNumber}"); SetRepositoryNumber(); redisLock.UnLock(); } } }
Redis分布式锁 RedisLock 类代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using StackExchange.Redis; namespace ConsoleTestRedis { /// <summary> /// Redis分布式锁 /// </summary> public class RedisLock { /// <summary> /// redis分布式连接管理器 /// </summary> public ConnectionMultiplexer _connectionMultiplexer { get; set; } /// <summary> /// 数据库 /// </summary> public IDatabase _database { get; set; } public RedisLock() { //使用的redis api 前提1、安装redis 2、NuGet包管理器添加 StackExchange.Redis _connectionMultiplexer = ConnectionMultiplexer.Connect("localhost:6379"); _database = _connectionMultiplexer.GetDatabase(0); } /// <summary> /// 锁住 /// </summary> public void Lock() { while (true) { //LockTake 参数说明 (锁名称,获取所得对象,过期时间) bool isLocked = _database.LockTake("redis_key", Thread.CurrentThread.ManagedThreadId, TimeSpan.FromSeconds(200)); if (isLocked) { break; } Thread.Sleep(200); } } /// <summary> /// 释放 /// </summary> public void UnLock() { //LockRelease 参数说明 (锁名称,获取所得对象) _database.LockRelease("redis_key", Thread.CurrentThread.ManagedThreadId); _connectionMultiplexer.Close(); } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleTestRedis { class Program { static void Main(string[] args) { Console.WriteLine("。。。。。商品秒杀开始。。。。。。"); Client client = new Client(); client.CleitRequest(); Console.ReadKey(); } } }
注意:
运行的时候要先启动redis服务器(如果未启动redis服务器,则使用RedisLock锁时会报连接错误)
效果如下:
对比效果(第一次使用RedisLock锁时候会启动慢一些,以后会很快)
1、未在ProductKill的秒杀方法KillProduct()添加RedisLock分布式锁的时候,
效果如下:
2、在ProductKill的秒杀方法KillProduct()添加RedisLock分布式锁的时候,
效果如下: