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緩存