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

xhtml

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實現分佈式鎖redis

 

x緩存

 

相關文章
相關標籤/搜索