Package Name | Version | Downloads |
---|---|---|
ClockSnowFlake |
这是一个基于.NET开源的改进版雪花算法组件,解决了原生雪花算法的时间回拨问题
- 支持自定义WorkId
- 基于时间序列,解决时间回拨问题
- 傻瓜式配置,开箱即用
- 关键实现代码
Install-Package ClockSnowFlake
public class Startup
{
//...
public void ConfigureServices(IServiceCollection services)
{
//configuration
services.AddSnowFlakeId(x => x.WorkId = 2);
}
}
[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/缓存等方式存储起来
- 还是支持最长 69 年多的运行时间
- 分布式实例规模由2^10(1024)降至2^7(128)
- 单实例每毫秒仍然支持 4096次请求
- 每个分布式实例支持最多 2^3(8) 次时间回拨