samcook / RedLock.net

An implementation of the Redlock algorithm in C#
MIT License
947 stars 167 forks source link

One day after two servers, the lock of one of the servers is false #79

Closed miaoyukai closed 2 years ago

miaoyukai commented 4 years ago

As the problem description.code show as below

    public class RedisLockHelp
    {
        private static RedLockFactory redLockFactory = null;

        static RedisLockHelp()
        {
            //string shadowEx = StringHelper.GetAppSetting<string>("redisconfig");
            var endPoints = new List<RedLockEndPoint>
            {
                new DnsEndPoint("redislock", 6001)
            };
            redLockFactory = RedLockFactory.Create(endPoints);
        }

        public static IRedLock GetRedLock(string key)
        {
            var expiry = TimeSpan.FromSeconds(5);
            var wait = TimeSpan.FromSeconds(3);
            var retry = TimeSpan.FromSeconds(1);

            // resource 锁定的对象
            // expiryTime 锁定过期时间,锁区域内的逻辑执行如果超过过期时间,锁将被释放
            // waitTime 等待时间,相同的 resource 如果当前的锁被其他线程占用,最多等待时间
            // retryTime 等待时间内,多久尝试获取一次
            var redLock = redLockFactory.CreateLock(key, expiry, wait, retry);

            return redLock;
        }
    }

use

var resource = $"key";

using (var redLock = RedisLockHelp.GetRedLock(resource)) // there are also non async Create() methods
{
    if (redLock.IsAcquired)
    {
        //Related insert operations
        result = InsertSessionRecord(sessionRecord);
    }
     //Logging that server is false
    NLog.LogManager.GetLogger("info").Info($"MessageRecordUpdateRequest入参:单聊会话 是否锁定:{redLock.IsAcquired},key:{resource}");
}

After running for a period of time, one of the machines will always become false.Restart the IIS application pool of that machine

miaoyukai commented 4 years ago

version 2.1.0

samcook commented 4 years ago

One of the machines will report IsAcquired == false if the other is holding the lock, and it isn't able to obtain it within the wait time (3 seconds in your example code above). However I wouldn't expect that this should happen every single time unless the lock truly is being held each time by the other machine.

You best options here are to check the value of Status and InstanceSummary properties for a bit more detailed information about why the lock wasn't able to be obtained.

If that doesn't help, you'll need to wire up a logger in the RedLockFactory.Create method (it takes an optional ILoggerFactory) and get some logs to find out exactly what is happening.

miaoyukai commented 4 years ago

One of the machines will report IsAcquired == false if the other is holding the lock, and it isn't able to obtain it within the wait time (3 seconds in your example code above). However I wouldn't expect that this should happen every single time unless the lock truly is being held each time by the other machine.

You best options here are to check the value of Status and InstanceSummary properties for a bit more detailed information about why the lock wasn't able to be obtained.

If that doesn't help, you'll need to wire up a logger in the RedLockFactory.Create method (it takes an optional ILoggerFactory) and get some logs to find out exactly what is happening.

thank you

miaoyukai commented 4 years ago

One of the machines will report IsAcquired == false if the other is holding the lock, and it isn't able to obtain it within the wait time (3 seconds in your example code above). However I wouldn't expect that this should happen every single time unless the lock truly is being held each time by the other machine.

You best options here are to check the value of Status and InstanceSummary properties for a bit more detailed information about why the lock wasn't able to be obtained.

If that doesn't help, you'll need to wire up a logger in the RedLockFactory.Create method (it takes an optional ILoggerFactory) and get some logs to find out exactly what is happening.

hello. Now I recorded the error log as follows: IsAcquired:False, Status:NoQuorum, InstanceSummary.Acquired:0; InstanceSummary.Error:1; InstanceSummary.Conflicted:0; key:u_u100676462:s_021_aa95833:2020-09-22

miaoyukai commented 4 years ago

One of the machines will report IsAcquired == false if the other is holding the lock, and it isn't able to obtain it within the wait time (3 seconds in your example code above). However I wouldn't expect that this should happen every single time unless the lock truly is being held each time by the other machine. You best options here are to check the value of Status and InstanceSummary properties for a bit more detailed information about why the lock wasn't able to be obtained. If that doesn't help, you'll need to wire up a logger in the RedLockFactory.Create method (it takes an optional ILoggerFactory) and get some logs to find out exactly what is happening.

I am a single Redis server

samcook commented 4 years ago

So the information you've provided there shows that an exception occurred while trying to acquire the lock with your redis server.

To find out exactly what that error is you'll need to inject an instance of ILoggerFactory in your RedLockFactory.Create call. From your example code it looks like you're using NLog, I believe the NLog.Extensions.Logging package has what you need to wire that up.

Once you have logs from RedLock, you should see something like Error locking lock instance {host}: {message} at the Debug log level.

miaoyukai commented 4 years ago

So the information you've provided there shows that an exception occurred while trying to acquire the lock with your redis server.

To find out exactly what that error is you'll need to inject an instance of ILoggerFactory in your RedLockFactory.Create call. From your example code it looks like you're using NLog, I believe the NLog.Extensions.Logging package has what you need to wire that up.

Once you have logs from RedLock, you should see something like Error locking lock instance {host}: {message} at the Debug log level.

I don't use .net core now

samcook commented 4 years ago

That shouldn't matter, it supports .NET Framework as well