Java 终端设备消息ID-雪花算法简化版


一、雪花算法-简化版

雪花算法(SnowFlake)是推特(Twitter)开源的分布式高并发环境生成消息唯一ID的方案,目前被广泛使用。 雪花算法相对UUID来说是有序的,它产生的ID是一个64位的long型数据,由固定值+时间戳+机器ID+序号组成,但传统行业的终端设备其实并不需要如此复杂的算法,那么今天我们就保留核心的部分,来实现一个简化的版本。

二、代码示例

简化版的雪花算法:unix时间戳 + 6位随机数 + 6位序列号 + 设备号 实际过程中6位随机数仅是作为冗余手段引入的,可以注释掉随机数部分的代码

package com.company.example;

import java.security.SecureRandom;

public class Utills {
          
   

    static final SecureRandom numberGenerator = new SecureRandom();

    static final long SEQUENCE_BIT = 6; // 序列号占用的位数
    static final long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT); // 序列号最大值
    static long SEQUENCE = 0L; // 毫秒内序列号
    static long LASTSTMP = -1L;// 上一次时间戳

    /**
     * 生成唯一消息ID
     */
    public static String generateMessageID(String deviceNo){
          
   
        // 生成6位随机数
        int random = numberGenerator.nextInt(1000000);
        // 自增序列号

        // 时间戳 + 毫秒内6位序列号
        long timeStamp =  System.currentTimeMillis();
        if(LASTSTMP == timeStamp){
          
   
            SEQUENCE = (SEQUENCE + 1) & MAX_SEQUENCE;
            if (SEQUENCE == 0L) {
          
   
                while(LASTSTMP == timeStamp){
          
   
                    timeStamp =  System.currentTimeMillis();
                }
            }
        } else {
          
   
            SEQUENCE = 0L;
        }
        LASTSTMP = timeStamp;

        // 消息ID: unix时间戳 + 6位随机数 + 6位序列号 + 设备号
        return timeStamp + String.format("%06d", random) + String.format("%06d", SEQUENCE) + deviceNo;
    }
}

三、总结

复杂的雪花算法核心的思想是:当前时间戳和上次时间戳比较,相等的情况下序列号自增(如果序列号已达最大,则死循环直到下一个时间戳),再与时间戳、设备号组合为一个ID。 利用雪花算法的关键部分,我们可以实现一个简单的消息ID生成器,适用于小型的并发环境。

经验分享 程序员 微信小程序 职场和发展