using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Timers; using Yitter.IdGenerator; using YuanXuan.IM.Infrastructure.Redis; namespace YuanXuan.IM.Api.Helper { /// /// IdWorker自动注册帮助类 需要先注册Redis /// public class WorkerIdAutoRegisterHelper { private static System.Timers.Timer _timer; public static IdGeneratorOptions GetIdGeneratorOptions() { byte workerIdBitLength = 6; var maxWorkId = Math.Pow(2, workerIdBitLength) - 1; var workIdKey = "idgen:workid"; var workId = GetNextWorkId(); while (!RedisHelper.Instance.SetNx($"{workIdKey}:{workId}", 1)) { // workId 已被占用,获取下一个workId workId = GetNextWorkId(); }; // 设置5分钟过期 RedisHelper.Instance.Expire($"{workIdKey}:{workId}", 60 * 5); // 设置定时器,每4分钟更新一次过期时间 SetTimer(4, (s, e) => { RedisHelper.Instance.Expire($"{workIdKey}:{workId}", 60 * 5); }); // WorkerIdBitLength + SeqBitLength 不超过 22 return new IdGeneratorOptions { WorkerIdBitLength = workerIdBitLength, SeqBitLength = 6, // 数值越高,性能越好,但是Id也越长 WorkerId = (ushort)workId }; long GetNextWorkId() { var workId = RedisHelper.Instance.IncrBy(workIdKey,1); if (workId > maxWorkId) { // 大于了最大可用WorkId,重置workId,并获取 RedisHelper.Instance.Set(workIdKey, 0); workId = RedisHelper.Instance.IncrBy(workIdKey, 1); } Console.WriteLine($"================================================分配到的workId:{workId}==============================================================================="); return workId; } } private static void SetTimer(int mins, ElapsedEventHandler eh) { // 创建一个 Timer 实例,并设置其相关属性 _timer = new System.Timers.Timer(TimeSpan.FromMinutes(mins).TotalMilliseconds); // 4 分钟 _timer.Elapsed += eh; _timer.AutoReset = true; // 设置 Timer 实例能否多次触发 _timer.Enabled = true; // 启动 Timer 实例 } } }