using FreeRedis; using Masuit.Tools; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Meeting.Infrastructure { public abstract class RedisHelper { private static RedisClient _instance; /// /// redis实例 /// public static RedisClient Instance { get { if (_instance == null) { throw new Exception("使用前初始化redis静态访问类 RedisHelper.Initialization(new FreeRedis.RedisClient(\"127.0.0.1:6379,password=123,defaultDatabase=13,maxpoolsize=50,prefix=key前辍\"));"); } return _instance; } } public static void SetLoginToken(long userId, string token) { var key = "Login_Token"; Instance.HSet(key, userId.ToString(), token); } public static void DeleteLoginToken(long userId) { var key = "Login_Token"; Instance.HDel(key, userId.ToString()); } /// /// 初始化redis静态访问类 RedisHelper.Initialization(new FreeRedis.RedisClient(\"127.0.0.1:6379,password=123,defaultDatabase=13,maxpoolsize=50,prefix=key前辍\")) /// /// public static void Initialization(string connectionString) { _instance = new FreeRedis.RedisClient(connectionString) { Serialize = (x) => x.ToJsonString(), Deserialize = (x, t) => JsonConvert.DeserializeObject(x, t), }; } internal static ThreadLocal rnd = new ThreadLocal(() => new Random()); /// /// 随机秒(防止所有key同一时间过期,雪崩) /// /// 最小秒数 /// 最大秒数 /// public static int RandomExpired(int minTimeoutSeconds, int maxTimeoutSeconds) => rnd.Value.Next(minTimeoutSeconds, maxTimeoutSeconds); /// /// 获取Redis分布式锁 /// /// 锁键 /// 锁值(建议使用GUID) /// 过期时间(秒) /// 是否获取成功 public static bool TryLock(string lockKey, string lockValue, int expireSeconds = 30) { return Instance.SetNx(lockKey, lockValue, expireSeconds); } /// /// 释放Redis分布式锁 /// /// 锁键 /// 锁值(必须与加锁时一致) /// 是否释放成功 public static bool ReleaseLock(string lockKey, string lockValue) { // 使用Lua脚本确保原子性:只有当锁的值匹配时才删除 const string luaScript = @" if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end"; var result = Instance.Eval(luaScript, new[] { lockKey }, new[] { lockValue }); return (long)result == 1; } /// /// 延长Redis锁的过期时间 /// /// 锁键 /// 锁值 /// 新的过期时间(秒) /// 是否续期成功 public static bool RenewLock(string lockKey, string lockValue, int expireSeconds) { // 使用Lua脚本确保原子性:只有当锁的值匹配时才更新过期时间 const string luaScript = @" if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('EXPIRE', KEYS[1], ARGV[2]) else return 0 end"; var result = Instance.Eval(luaScript, new[] { lockKey }, new[] { lockValue, expireSeconds.ToString() }); return (long)result == 1; } } }