分布式锁 redlock(三)

本文介绍 redlock

github 地址 GitHub - samcook/RedLock.net:C 语言中 Redlock 算法的实现#

该程序集 可以 使用 独立的 非主从复制的 redis 也可以使用 主从复制的redis

他也依赖于 StackExchange.Redis

 

这种方式 也需要考虑 锁过期时间 和等待时间  只要 加锁数量 大于 redis总数/2 +1 就人为 加锁成功

所以 redis 节点数 最好为 3 5 7 9 奇数个

 

主从复制的  代码 这是官网上的

var redlockEndPoints = new List<RedLockEndPoint>
{
	new RedLockEndPoint
	{
		EndPoints =
		{
			new DnsEndPoint("replicatedset1-server1", 6379),
			new DnsEndPoint("replicatedset1-server2", 6379),
			new DnsEndPoint("replicatedset1-server3", 6379)
		}
	},
	new RedLockEndPoint
	{
		EndPoints =
		{
			new DnsEndPoint("replicatedset2-server1", 6379),
			new DnsEndPoint("replicatedset2-server2", 6379),
			new DnsEndPoint("replicatedset2-server3", 6379)
		}
	},
	new RedLockEndPoint
	{
		EndPoint = new DnsEndPoint("independent-server", 6379)
	}
};

var redlockFactory = RedLockFactory.Create(redlockEndPoints);

 

非主从复制的 

var endPoints = new List<RedLockEndPoint>
{
	new DnsEndPoint("redis1", 6379),
	new DnsEndPoint("redis2", 6379),
	new DnsEndPoint("redis3", 6379)
};
var redlockFactory = RedLockFactory.Create(endPoints);

  

上测试

 

上测试代码  测试代码 我只用了 一个redis

 public class RedLockTest
    {
        public static readonly string RedLockKey = "redlock";
        public static readonly string RedLockTotalKey = "redlocktotal";
        public static async void Test()
        {
            var existingConnectionMultiplexer1 = ConnectionMultiplexer.Connect("192.168.0.168:6379");
            //var existingConnectionMultiplexer2 = ConnectionMultiplexer.Connect("redis2:6379");
            //var existingConnectionMultiplexer3 = ConnectionMultiplexer.Connect("redis3:6379");
            var multiplexers = new List<RedLockMultiplexer>
            {
                existingConnectionMultiplexer1,
                //existingConnectionMultiplexer2,
                //existingConnectionMultiplexer3
            };
            var redlockFactory = RedLockFactory.Create(multiplexers);
            var resource = RedLockTest.RedLockKey;
            var expiry = TimeSpan.FromSeconds(30);
            var wait = TimeSpan.FromSeconds(10);
            var retry = TimeSpan.FromSeconds(1);
            //锁的超时时间要大于程序执行的时间,否则多个客户端可能同时获取锁。充分预估使用锁的业务代码执行时间,
            //该时间不宜过长也不宜过短,过短,可能使锁发生错误;过长,客户端异常时可能会影响执行效率。
            try
            {
                await using (var redLock = await redlockFactory.CreateLockAsync(resource, expiry, wait, retry)) // there are also non async Create() methods
                {
                    if (!redLock.IsAcquired)
                    {
                        Console.WriteLine($"取锁失败,当前线程为{Thread.CurrentThread.ManagedThreadId}");
                        return;
                    }
                    using (RedisClient redisClient = new RedisClient("192.168.0.168:6379"))
                    {
                        int total = redisClient.Get<int>(RedLockTest.RedLockTotalKey);
                        if (total <= 0)
                        {
                            Console.WriteLine($"抢购已经结束了{total},当前线程{Thread.CurrentThread.ManagedThreadId}");
                            return;
                        }
                        total -= 1;
                        redisClient.Set(RedLockTest.RedLockTotalKey, total);
                        Console.WriteLine($"抢购成功了剩余总数为{total},当前线程为{Thread.CurrentThread.ManagedThreadId}");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"报错了{ex.Message}");
            }
        }
    }

  

 

posted on 2023-11-12 00:41  是水饺不是水饺  阅读(89)  评论(0)    收藏  举报

导航