什么是时间回拨问题
- 雪花算法通过时间来即将作为id的区分标准之一,对于同一台id生成机器,它通过时间和序号保证id不重复
- 当机器出现问题,时间可能回到之前,此时,时间就不能区分
- 又或者因为闰秒的出现,导致时间回拨
如何解决
方法1 直接抛出异常
- 不管3X7==21,直接抛出异常
- 将问题交给人工解决
- 这种方法也是原始的雪花算法,百度的uid-generator采用的
- 太过简单,显然不好
方法2 延迟等待
- 这种时间回拨(回跳)或许只出现一次,也许只是机器出现了小问题,所以产生
- 对于这种场景,没有必要抛出异常,中断业务
- 此时,将当前线程阻塞3ms,之后再获取时间,看时间是否比上一次请求的时间大
- 如果大了,说明恢复正常了,则不用管
- 如果还小,说明真出问题了,则抛出异常,呼唤程序员处理
- 实际应用项目: 美团的leaf, 用如果时间差在5ms内,则等待 时间差<<1, 然后再判断
方法3 备用机
- 当前机器出现问题,则换一台机器
- 通过高可用来解决该问题
方法4 采用之前最大时间
- 本身得出时间回拨结论就是通过当前时间和上次最后(大)的时间进行比较
- 那么此时可以采用上次最大时间的最大序号之后的序号来进行继续使用
- 从而保证了唯一性
方法5 追赶时间
- 可以采取这样的暴力思路,因为当前的时间回拨了,比之前的时间慢
- 那么我们便加速追赶时间
- 首先,不返回id
- 然后将我们的seq增加比如1024个,然后判断是否回拨,如果不是,再加1024
- 当seq超过了12位的maxSeq时,按照雪花算法的逻辑,时间便会进位,借用下个时间的seq
- 此时就实现了时间的加速
- 经过若干个加速,则可以实现时间正常