public static void RedisLockV2() { var lockTimeout = 5000;//单位是毫秒 var currentTime = DateTime.Now.ToUnixTime(true); if (SetNxV2("lockkey",DateTime.Now.ToUnixTime(true)+lockTimeout)) { //设置过期时间 redisClient.Expire("lockkey", TimeSpan.FromMilliseconds(5000)); //TODO:一些业务逻辑代码 Console.WriteLine("处理业务ing"); Thread.Sleep(100000); Console.WriteLine("处理业务ed"); //最后释放锁 Remove("lockkey"); } else { //未获取到锁,继续判断,判断时间戳看看是否可以重置并获取锁 var lockValue = redisClient.Get("lockkey"); var time = DateTime.Now.ToUnixTime(true); if (!string.IsNullOrEmpty(lockValue) && time> lockValue.ToInt64()) { //再次用当前时间戳getset //返回固定key的旧值,旧值判断是否可以获取锁 var getsetResult = redisClient.GetSet("lockkey", time); if (getsetResult == null || (getsetResult != null && getsetResult == lockValue)) { Console.WriteLine("获取到Redis锁了"); //真正获取到锁 redisClient.Expire("lockkey", TimeSpan.FromMilliseconds(5000)); //TODO:一些业务逻辑代码 //..... //..... Console.WriteLine("处理业务"); //最后释放锁 Remove("lockkey"); } else { Console.WriteLine("没有获取到锁"); } } else { Console.WriteLine("没有获取到锁"); } } }
现在,Redis中的情况如下:
我们运行上面的代码,结果如下:
副本.exe中添加一行代码。来模拟这种场景:有A、B两台服务器在跑这个应用,当A台应用跑到:setnx成功但是还没有设置过期时间的时候,突然重启服务,这个时候在分布式环境中就会发生死锁的问题,因为你没有设置过期时间
我们先执行Lottery.ThriftRpc - 副本.exe,等Redis里面有值了,并且这个key是没有过期时间,再关闭掉该程序:
然后,再执行Lottery.ThriftRpc.exe
看,我们是不是解决了该问题,至于过期时间设置为多少要结合你的具体业务处理时间来计算出一个合理的值,好了,聊到这里关于Redis的分布式锁就讲完了,希望对你有帮助,谢谢。
四、总结:
上面的示例中Redis的组件用的是CSRedisCore,这里只是自己的一点体会,如果你有更好的办法,可以在评论区讨论,关于Redis的理论讲解有太多的文章了,大家可以参考,关于Redis的文章我只总结工作中遇到的一些问题,关于文章中的源码,我就不提供了,太简单了。后面我会不定期分享一些Redis的问题,希望大家多多支持。
以上所述是小编给大家介绍的ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
您可能感兴趣的文章: