lihongjie0209 / myblog

4 stars 0 forks source link

分布式ID: Snowflake #63

Open lihongjie0209 opened 4 years ago

lihongjie0209 commented 4 years ago

Snowflake是Twitter提出来的一个算法,其目的是生成一个64bit的整数:

image

lihongjie0209 commented 4 years ago

源码分析

https://github.com/downgoon/snowflake/blob/master/src/main/java/xyz/downgoon/snowflake/Snowflake.java

初始化机器ID


    public Snowflake(long datacenterId, long workerId) {
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException(
                    String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
        }
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(
                    String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
        }

        this.datacenterId = datacenterId;
        this.workerId = workerId;
    }

获取ID

时钟回拨直接抛出异常

long currTimestamp = timestampGen();

        if (currTimestamp < lastTimestamp) {
            throw new IllegalStateException(
                    String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
                            lastTimestamp - currTimestamp));
        }

如果处于相同的时间, 那么递增序列号, 否则从0开始记录序列号

if (currTimestamp == lastTimestamp) {
            sequence = (sequence + 1) & maxSequence;
            if (sequence == 0) { // overflow: greater than max sequence
                currTimestamp = waitNextMillis(currTimestamp);
            }

        } else { // reset to 0 for next period/millisecond
            sequence = 0L;
        }

返回

// track and memo the time stamp last snowflake ID generated
        lastTimestamp = currTimestamp;

        return ((currTimestamp - epoch) << timestampShift) | //
                (datacenterId << datacenterIdShift) | //
                (workerId << workerIdShift) | // new line for nice looking
                sequence;