分布式雪花算法生成唯一ID

雪花算法组成
在这里插入图片描述
10bit工作进程位:用来记录工作机器的id,包括5位datacenterId和5位workerId;5位(bit)可以表示的最大正整数是31,即可以用0,1,2,3,…31这32个数字,来表示不同的datacenterId和workerId

Hutool工具包

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.16</version>
</dependency>

Snowflake需自行保证单例,否则多个对象生成ID会导致重复

代码

package com.lyods.base.utils;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @creator linhy
 * @date 2021-11-16
 * @descrption 获取雪花算法ID
 *
 */
public class SnowFlakeUtil {

    private final static Logger log = LoggerFactory.getLogger(SnowFlakeUtil.class);

    private static long workerId = 0;

    private volatile static Snowflake snowflake = null;
    private volatile static SnowFlakeUtil sfu = null;

    /**
     * 单例
     */
    private SnowFlakeUtil() {
    }

    public static SnowFlakeUtil getInstance() {
        if (null == sfu) {
            synchronized (SnowFlakeUtil.class) {
                if (null == sfu) {
                    sfu = new SnowFlakeUtil();
                }
            }
        }
        return sfu;
    }

    /**
     * 获取ID
     * @return
     */
    public long snowflakeId() {
        if (null == snowflake) {
            snowflake = getSnowflake();
        }
        return snowflake.nextId();
    }

    /**
     * 获取ID(自定义工作机器ID)
     * @param workerId     终端ID
     * @param dataCenterId 数据中心ID
     * @return
     */
    public long snowflakeId(long workerId, long dataCenterId) {
        if (null == snowflake) {
            snowflake = getSnowflake(workerId, dataCenterId);
        }
        return snowflake.nextId();
    }

    /**
     * Snowflake带参对象获取
     * @return
     */
    private synchronized Snowflake getSnowflake(long workerId, long dataCenterId) {
        snowflake = IdUtil.getSnowflake(workerId, dataCenterId);
        return snowflake;
    }

    /**
     * Snowflake无参对象获取
     * @return
     */
    private synchronized Snowflake getSnowflake() {
        snowflake = new Snowflake();
        return snowflake;
    }

    @PostConstruct
    public void init() {
        try {
            workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr());
            log.info("当前机器的workId: {}", workerId);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("当前机器的workId获取失败", e);
            workerId = NetUtil.getLocalhostStr().hashCode();
        }
    }

}

线程池30线程测试

ExecutorService executorService = Executors.newFixedThreadPool(5);
Stream.iterate(0, x -> x + 1).limit(30).forEach(x -> {
    executorService.submit(() -> {
        long id = SnowFlakeUtil.getInstance().snowflakeId();
        System.out.println(id);
    });
});

结果
在这里插入图片描述

  • 优点
    时间戳位在高位,ID趋势递增(几千页的分页下可以根据最后一条数据ID进行分页提高效率),生成ID性能高,不依赖第三方系统,分布式系统内不会产生ID碰撞(由datacenter和workerId作区分)
  • 缺点
    回拨本机时间可能导致时间戳相同,ID重复,分布式下不同机器可能时间不完全同步
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java雪花算法是一种分布式id生成算法,它使用一个64位的long型数字作为全局唯一id。该算法基于时间戳和序列号自增的方式,可以在高并发分布式环境下生成不重复的id,每秒可生成百万个不重复的id。此算法简单且高效,不依赖于第三方库或中间件。因此,使用Java雪花算法可以轻松实现全局唯一id生成。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ID生成方式Java——雪花算法](https://blog.csdn.net/qq_42900213/article/details/126172808)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [SnowFlake 雪花算法详解与实现](https://blog.csdn.net/chenlixiao007/article/details/123956128)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [java 雪花算法生成ID](https://blog.csdn.net/qq_37996327/article/details/105650644)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值