65 lines
2.0 KiB
C#
65 lines
2.0 KiB
C#
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 实例
|
||
}
|
||
}
|