using Dolphin.ExamPictureCut.Constants; using System.Timers; using Yitter.IdGenerator; using Timer = System.Timers.Timer; namespace Dolphin.ExamPictureCut.Extensions; public class IdExt { public static IdGeneratorOptions GetIdGeneratorOptions(string uniqueValue) { byte workerIdBitLength = 8; var maxWorkId = Math.Pow(2, workerIdBitLength) - 1; //63 var workIdKey = $"{uniqueValue}idgen:workid"; var workId = GetNextWorkId(); while (!RedisHelper.SetNx($"{workIdKey}:{workId}", SysConsts.AppName)) { // workId 已被占用,获取下一个workId workId = GetNextWorkId(); }; // 设置5分钟过期 RedisHelper.Expire($"{workIdKey}:{workId}", 60 * 5); // 设置定时器,每4分钟更新一次过期时间 SetTimer(4, (s, e) => { RedisHelper.Expire($"{workIdKey}:{workId}", 60 * 5); }); // WorkerIdBitLength + SeqBitLength 不超过 22 return new IdGeneratorOptions { WorkerIdBitLength = workerIdBitLength, //SeqBitLength = 6, // 数值越高,性能越好,但是Id也越长 WorkerId = (ushort)workId }; long GetNextWorkId() { var workId = RedisHelper.IncrBy(workIdKey); if (workId > maxWorkId) { // 大于了最大可用WorkId,重置workId,并获取 RedisHelper.Set(workIdKey, -1); workId = RedisHelper.IncrBy(workIdKey); } return workId; } } private static Timer _timer; private static void SetTimer(int mins, ElapsedEventHandler eh) { // 创建一个 Timer 实例,并设置其相关属性 _timer = new Timer(TimeSpan.FromMinutes(mins).TotalMilliseconds); // 4 分钟 _timer.Elapsed += eh; _timer.AutoReset = true; // 设置 Timer 实例能否多次触发 _timer.Enabled = true; // 启动 Timer 实例 } }