Java雪花ID生成器

在分布式系统中,生成全局唯一的ID是一个很常见的需求。雪花算法是Twitter开源的一种分布式ID生成算法,能够保证在分布式系统中生成全局唯一的ID,且性能高效。

雪花算法原理

雪花算法生成的ID是一个64位的整数,其中包含了时间戳、机器ID和序列号三部分。具体如下:

  • 时间戳:41位,毫秒级,可以用69年。这里需要注意的是,时间戳是相对于一个固定的时间点的增量值,不是系统的当前时间。
  • 机器ID:10位,用来标识不同的机器。
  • 序列号:12位,代表同一毫秒内生成的不同ID的序号。

Java实现

下面是一个简单的Java实现雪花ID生成器的代码示例:

public class SnowflakeIdGenerator {
    
    private final long startTimestamp = 1619827200000L;
    private final long machineIdBits = 10L;
    private final long sequenceBits = 12L;
    
    private long machineId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;
    
    public SnowflakeIdGenerator(long machineId) {
        if (machineId < 0 || machineId >= (1 << machineIdBits)) {
            throw new IllegalArgumentException("Machine ID must be between 0 and " + ((1 << machineIdBits) - 1));
        }
        this.machineId = machineId;
    }
    
    public synchronized long generateId() {
        long timestamp = System.currentTimeMillis() - startTimestamp;
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards, unable to generate ID");
        }
        if (timestamp == lastTimestamp) {
            sequence = (sequence + 1) % (1 << sequenceBits);
            if (sequence == 0) {
                timestamp = waitNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }
        
        lastTimestamp = timestamp;
        
        return (timestamp << (machineIdBits + sequenceBits)) | (machineId << sequenceBits) | sequence;
    }
    
    private long waitNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis() - startTimestamp;
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis() - startTimestamp;
        }
        return timestamp;
    }
}

雪花ID生成器流程图

flowchart TD
    Start --> CheckTimestamp
    CheckTimestamp -->|Timestamp < LastTimestamp| UpdateSequence
    CheckTimestamp -->|Timestamp == LastTimestamp| IncrementSequence
    CheckTimestamp -->|Timestamp > LastTimestamp| ResetSequence
    UpdateSequence --> WaitNextMillis
    IncrementSequence --> GenerateId
    ResetSequence --> GenerateId
    GenerateId --> End
    WaitNextMillis --> UpdateSequence

旅程图

journey
    title 雪花ID生成器
    section 生成ID
        GenerateID(生成唯一ID)
        GenerateID --> CheckTimestamp(检查时间戳)
        CheckTimestamp -->|时间戳 < 上次时间戳| UpdateSequence(更新序号)
        CheckTimestamp -->|时间戳 == 上次时间戳| IncrementSequence(增加序号)
        CheckTimestamp -->|时间戳 > 上次时间戳| ResetSequence(重置序号)
        UpdateSequence --> WaitNextMillis(等待下一个时间戳)
        IncrementSequence --> GenerateID
        ResetSequence --> GenerateID

结语

通过雪花算法,我们可以在分布式系统中生成全局唯一的ID,避免了ID冲突的问题。上面的Java示例代码展示了如何实现一个简单的雪花ID生成器,希望对你有所帮助。如果有任何问题或建议,欢迎留言交流。