集群服務器+定時任務(Quartz) 重復執行的問題


x

StackExchange.Redis


private readonly IDatabase _db;

string key = string.Concat("{自己命名的Redis前綴}", task.TaskDetailsId);
//獲取本機服務器IP地址
string valIp = GetLocalIP();
//Redis緩存中的IP地址,
var valIpRedis = _db.StringGet(redisKey);

            /*
             * 方案1.每次都獲取鎖(redis.LockTake),而不去判斷緩存中的值(valIpRedis)
             * 方案2.每次先判斷緩存中的值(valIpRedis),沒有緩存再去獲取鎖.
             * 目前采用的是方案2.
             *
             *      如果以后執行周期和緩存過期時間發生改變可能存在的風險:
             *      1.方案1風險:如果設置的過期時間比執行周期長,服務器都獲取不到鎖了,任務這次就不會執行,只能等到緩存清除之后才可以獲取到鎖.(例如:過期時間24H,執行周期1H,那么24H內,只會執行1次)
             *      2.方案2風險:服務器A剛獲取完緩存的IP地址,就過期了,而服務器B此時也剛好獲取到了鎖.就會執行兩次.(例如:過期時間1H,執行周期1H,那么1H內,可能會執行2次)
             */
            if (valIpRedis != null && valIpRedis == valIp)
            {
                isCanRun = true;
            }
            //如果Redis中沒有緩存,去獲取鎖,獲取成功,即可執行...
            else if (redis.LockTake(key, valIp, TimeSpan.FromMilliseconds(taskExpiry)))
            {
                isCanRun = true;
            }
            if (isCanRun)
       {

                    //記錄日志{XX任務開始執行,服務器IP地址為xx.xx.xx.xx}
                    //開始執行各個定時任務{Quartz}
                    ((ITask)Activator.CreateInstance(Type.GetType("Your Class Type"))).Execute(task);

       }

 

 傳送門

C#通過Redis實現分布式鎖

 

x

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM