ClockSnowFlake 是 一个基于.NET开源的改进版雪花算法组件,这个库主要解决了原生雪花算法的时间回拨问题。
ClockSnowFlake 傻瓜式配置,开箱即用,支持自定义 WorkId。
如何使用?
1.通过 Nuget 安装 ClockSnowFlake。
Install-Package ClockSnowFlake
2.修改 Startup.cs
public class Startup
{
//...
public void ConfigureServices(IServiceCollection services)
{
//configuration
services.AddSnowFlakeId(x => x.WorkId = 2);
}
}
3.使用 IdGener 生成 Id
[ApiController]
[Route("[controller]/[action]")]
public class SnowFlakeController : ControllerBase
{
/// <summary>
/// 获取Id
/// </summary>
[HttpGet]
public long GetId()
{
return IdGener.GetLong();
}
}
雪花算法的时间回拨问题
简单说就是时间被调整回到了之前的时间,由于雪花算法重度依赖机器的当前时间,所以一旦发生时间回拨,将有可能导致生成的 ID 可能与此前已经生成的某个 ID 重复(前提是刚好在同一毫秒生成 ID 时序列号也刚好一致),这就是雪花算法最经常讨论的问题。
这个现象发生的原因可能有,网络时间校准、人工设置错误、出现负闰秒等。
在原生的雪花算法中,出现时间回拨问题后,会支持抛出异常,由应用来处理错误, 如果是在一个并发不高或者请求量不大的业务系统中,错误等待或者重试的策略问题不大,但是如果是在一个高并发的系统中,这种策略显得过于粗暴。
如何解决?
这里采用的是一种基于修改扩展位的思路,基于时钟序列的雪花算法 二进制64位长整型数字:1bit保留 + 41bit时间戳 + 3位时钟序列 + 7bit机器 + 12bit序列号。
如上图,将原本10位的机器码拆分成3位时钟序列及7位机器码,发生时间回拨的时候,时间已经发生了变化,那么这时将时钟序列新增1位,重新定义整个雪花Id 为了避免实例重启引起时间序列丢失,因此时钟序列最好通过DB/缓存等方式存储起来。
评论区