id生成器,分布式ID自增算法(Snowflake 算法)

àì夳堔傛蜴生んèń 2022-05-19 04:21 412阅读 0赞

接口:

  1. /**
  2. * id生成器
  3. */
  4. public interface IdGenerator {
  5. String next();
  6. }

实现类:

  1. /**
  2. * 分布式ID自增算法<br/>
  3. * 来自网络Twitter Snowflake 算法
  4. *
  5. */
  6. public class DistributedIdGenerator implements IdGenerator{
  7. private final long workerId;
  8. private final static long twepoch = 1361753741828L;
  9. private long sequence = 0L;
  10. private final static long workerIdBits = 4L;
  11. public final static long maxWorkerId = -1L ^ -1L << workerIdBits;
  12. private final static long sequenceBits = 10L;
  13. private final static long workerIdShift = sequenceBits;
  14. private final static long timestampLeftShift = sequenceBits + workerIdBits;
  15. public final static long sequenceMask = -1L ^ -1L << sequenceBits;
  16. private long lastTimestamp = -1L;
  17. public DistributedIdGenerator(final long workerId) {
  18. super();
  19. if (workerId > maxWorkerId || workerId < 0) {
  20. throw new IllegalArgumentException(String.format(
  21. "worker Id can't be greater than %d or less than 0",
  22. maxWorkerId));
  23. }
  24. this.workerId = workerId;
  25. }
  26. public synchronized String next() {
  27. long timestamp = this.timeGen();
  28. if (this.lastTimestamp == timestamp) {
  29. this.sequence = (this.sequence + 1) & sequenceMask;
  30. if (this.sequence == 0) {
  31. System.out.println("###########" + sequenceMask);
  32. timestamp = this.tilNextMillis(this.lastTimestamp);
  33. }
  34. } else {
  35. this.sequence = 0;
  36. }
  37. if (timestamp < this.lastTimestamp) {
  38. try {
  39. throw new Exception(
  40. String.format(
  41. "Clock moved backwards. Refusing to generate id for %d milliseconds",
  42. this.lastTimestamp - timestamp));
  43. } catch (Exception e) {
  44. e.printStackTrace();
  45. }
  46. }
  47. this.lastTimestamp = timestamp;
  48. long nextId = ((timestamp - twepoch << timestampLeftShift))
  49. | (this.workerId << workerIdShift) | (this.sequence);
  50. return "" + nextId;
  51. }
  52. private long tilNextMillis(final long lastTimestamp) {
  53. long timestamp = this.timeGen();
  54. while (timestamp <= lastTimestamp) {
  55. timestamp = this.timeGen();
  56. }
  57. return timestamp;
  58. }
  59. private long timeGen() {
  60. return System.currentTimeMillis();
  61. }
  62. }

应用实例:

  1. @Service
  2. public class StudentsApplication(){
  3. @Autowired
  4. private IdGenerator idGenerator;
  5. public void add(){
  6. Student s = new Student();
  7. s.setId(idGenerator.next());
  8. }
  9. }

来自网络Twitter Snowflake 算法

发表评论

表情:
评论列表 (有 0 条评论,412人围观)

还没有评论,来说两句吧...

相关阅读

    相关 分布式IDSnowFlake算法

    常见的分布式ID方法: 1、UUID UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。对入库性能有影响(请了解下B-Tree索引的分裂)。 2、数据库