springboot集成uid-gengrator生成分布式id

一、简介

uid-generator是由百度技术部开发,GitHub地址

UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器

Snowflake算法

在这里插入图片描述
Snowflake算法描述:指定机器 & 同一时刻 & 某一并发序列,是唯一的。据此可生成一个64 bits的唯一ID(long)。默认采用上图字节分配方式:

sign(1bit)固定1bit符号标识,即生成的UID为正数。
delta seconds (28 bits)当前时间,相对于时间基点"2016-05-20"的增量值,单位:秒,最多可支持约8.7年
worker id (22 bits)机器id,最多可支持约420w次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃,后续可提供复用策略。
sequence (13 bits)每秒下的并发序列,13 bits可支持每秒8192个并发。

二、使用Spring boot项目集成uid-generator

2.1 将项目下载之后生成文件

在这里插入图片描述

下载完成后使用IDEA打开

在这里插入图片描述

复制生成的文件夹到maven仓库

在这里插入图片描述

我的maven仓库安装到了d盘

在这里插入图片描述

之后就可以使用标签引入了

2.2项目中引入uid-generator依赖,并排除其中的mybatis依赖

如果项目是SpringBoot+Mybatisplus,UidGenerator是Spring+Mybatis,直接引入uid-generator之后,本地项目启动就会出现创建SqlSessionFactory报错,所以,直接将uid-generator中的mybatis相关依赖排除。避免出现不必要的启动问题

<dependency>
    <groupId>com.baidu.fsg</groupId>
    <artifactId>uid-generator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <exclusions>
        <exclusion>
            <groupId>org.mybatis</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2.3 创建数据库表

DROP TABLE IF EXISTS WORKER_NODE;
CREATE TABLE WORKER_NODE
(
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name',
PORT VARCHAR(64) NOT NULL COMMENT 'port',
TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'launch date',
MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time',
CREATED TIMESTAMP NOT NULL COMMENT 'created time',
PRIMARY KEY(ID)
)
 COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB;

2.4 生成实体类与mapper

2.4.1实体类
import java.util.Date;

public class WorkerNode {

    private Long id;

    private String hostName;

    private String port;

    private Integer type;

    private Date LaunchDate;

    private Date modified;

    private Date created;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Date getLaunchDate() {
        return LaunchDate;
    }

    public void setLaunchDate(Date launchDate) {
        LaunchDate = launchDate;
    }

    public Date getModified() {
        return modified;
    }

    public void setModified(Date modified) {
        this.modified = modified;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    @Override
    public String toString() {
        return "WorkerNode{" +
                "id=" + id +
                ", hostName='" + hostName + '\'' +
                ", port='" + port + '\'' +
                ", type=" + type +
                ", LaunchDate=" + LaunchDate +
                ", modified=" + modified +
                ", created=" + created +
                '}';
    }
}

2.4.2 mapper与mapper.xml
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface WorkerNodeMapper {

    int addWorkerNode(WorkerNode workerNodeEntity);


    WorkerNode getWorkerNodeByHostPort(@Param("host") String host, @Param("port") String port);

}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lq.mapper.WorkerNodeMapper">
    <resultMap id="BaseResultMap"
               type="com.lq.entity.pojo.WorkerNode">
        <id column="ID" jdbcType="BIGINT" property="id" />
        <result column="HOST_NAME" jdbcType="VARCHAR" property="hostName" />
        <result column="PORT" jdbcType="VARCHAR" property="port" />
        <result column="TYPE" jdbcType="INTEGER" property="type" />
        <result column="LAUNCH_DATE" jdbcType="DATE" property="launchDate" />
        <result column="MODIFIED" jdbcType="TIMESTAMP" property="modified" />
        <result column="CREATED" jdbcType="TIMESTAMP" property="created" />
    </resultMap>

    <insert id="addWorkerNode" useGeneratedKeys="true" keyProperty="id"
            parameterType="com.lq.entity.pojo.WorkerNode">
        INSERT INTO WORKER_NODE
        (HOST_NAME,
         PORT,
         TYPE,
         LAUNCH_DATE,
         MODIFIED,
         CREATED)
        VALUES (
                   #{hostName},
                   #{port},
                   #{type},
                   #{launchDate},
                   NOW(),
                   NOW())
    </insert>

    <select id="getWorkerNodeByHostPort" resultMap="BaseResultMap">
        SELECT
            ID,
            HOST_NAME,
            PORT,
            TYPE,
            LAUNCH_DATE,
            MODIFIED,
            CREATED
        FROM
            WORKER_NODE
        WHERE
            HOST_NAME = #{host} AND PORT = #{port}
    </select>
</mapper>

注:
在这里插入图片描述

修改对应位置为自己实体类与mapper所在位置

2.5 service与impl

  • service
/**
 * @注释
 */
public interface IWorkerNodeService {

    public long genUid();
}
  • serviceimpl
import com.baidu.fsg.uid.UidGenerator;
import com.lq.service.IWorkerNodeService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 */
@Service
public class WorkerNodeServiceImpl implements IWorkerNodeService {
    @Resource
    private UidGenerator uidGenerator;

    @Override
    public long genUid() {
        return uidGenerator.getUID();
    }
}

2.6 添加配置类

在这里插入图片描述

2.6.1 DisposableWorkerIdAssigner
import com.baidu.fsg.uid.utils.DockerUtils;
import com.baidu.fsg.uid.utils.NetUtils;
import com.baidu.fsg.uid.worker.WorkerIdAssigner;
import com.baidu.fsg.uid.worker.WorkerNodeType;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 */
public class DisposableWorkerIdAssigner implements WorkerIdAssigner {

    @Resource
    private WorkerNodeMapper workerNodeMapper;

    @Override
    @Transactional
    public long assignWorkerId() {
        WorkerNode workerNode = buildWorkerNode();

        workerNodeMapper.addWorkerNode(workerNode);

        return workerNode.getId();
    }

    private WorkerNode buildWorkerNode() {
        WorkerNode workNode = new WorkerNode();
        if (DockerUtils.isDocker()) {
            workNode.setType(WorkerNodeType.CONTAINER.value());
            workNode.setHostName(DockerUtils.getDockerHost());
            workNode.setPort(DockerUtils.getDockerPort());
            workNode.setLaunchDate(new Date());
        } else {
            workNode.setType(WorkerNodeType.ACTUAL.value());
            workNode.setHostName(NetUtils.getLocalAddress());
            workNode.setPort(System.currentTimeMillis() + "-" + RandomUtils.nextInt(100000));
            workNode.setLaunchDate(new Date());
        }

        return workNode;
    }
}
2.6.2 WorkerNodeConfig
import com.baidu.fsg.uid.UidGenerator;
import com.baidu.fsg.uid.impl.CachedUidGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/** 
 */
@Configuration
public class WorkerNodeConfig {

    @Bean("disposableWorkerIdAssigner")
    public DisposableWorkerIdAssigner disposableWorkerIdAssigner(){
        return new DisposableWorkerIdAssigner();
    }

    @Bean("cachedUidGenerator")
    public UidGenerator uidGenerator(DisposableWorkerIdAssigner disposableWorkerIdAssigner){
        CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
        cachedUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner);
        return cachedUidGenerator;
    }
}

2.7 测试

import com.lq.service.IWorkerNodeService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 */
@SpringBootTest
public class UidGenerateTest {

    @Resource
    private IWorkerNodeService workerNodeService;

    @Test
    public void getUid() {
        List<Long> list = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            long uid = workerNodeService.genUid();
            list.add(uid);
        }
        AtomicInteger num = new AtomicInteger();
        list.forEach(l -> {
            System.out.println("第" + num.getAndIncrement() + "个id为 = " + l);
        });
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/681494.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SD6210A 低噪声可调电荷泵DC/DC转换器芯片IC

一般描述 该SD6210A是一种低噪声&#xff0c;恒定频率(1.20MHz)开关电容电压倍增器。它产生一个调节输出电压从2.8V到5V的输入与高达250mA的输出电流。低外部零件数(一个飞行电容器和两个小旁路电容的VIN和VOUT)使SD6210A非常适合小型&#xff0c;电池供电的应用新的电荷…

元宇宙数字藏品交易所,未来发展的大趋势

随着科技的飞速进步&#xff0c;元宇宙以其独特的魅力为数字世界绘制了一幅前所未有的宏伟蓝图。在这一宏大的背景下&#xff0c;数字藏品交易所作为连接虚拟与现实的桥梁&#xff0c;正以其卓越的优势&#xff0c;引领着数字藏品市场迈向新的高度。 首先&#xff0c;元宇宙为…

HBuilderX编写APP一、获取token

一、新建项目 二、从onenet获取key.js 1、下载之后的压缩包&#xff0c;解压2、关键就是找到key.js 3、将这个key.js复制到刚才的目录下面去 4、这个key.js文件就是生成token的代码 5、只要调用createCommonToken(params)这个函数&#xff0c;就可以实现生成token了 其中onload…

如何将OnePlus手机上的文件轻松传输到Mac(3种简便方法)

拥有一台OnePlus手机&#xff0c;意味着你拥有了一台性能强劲、功能丰富的Android设备。但当手机存储空间告急&#xff0c;或者你想要更好地管理和备份个人数据时&#xff0c;将文件传输到Mac电脑上无疑是一个明智的选择。本文将为你介绍三种简单有效的方法&#xff0c;帮助你轻…

十大排序-冒泡排序

算法原理如下&#xff1a; 给出一组数据&#xff1b;比较相邻的元素。如果第一个比第二个大&#xff0c;互换两个值。对每一组相邻元素同样方式比较&#xff0c;从开始的第一组到结束的最后一组。最后的元素会是最大数。除了排列好的最大数&#xff0c;针对所有元素重复以上步…

十、结果处理器

这一章和上一章参数处理器类似 首先是在XML解析的时候&#xff0c;顺便解析resultMap和resultType&#xff0c;一般更多的可能用的是resultType&#xff0c;为了实现统一&#xff0c;使用 resultType 的情况下&#xff0c;Mybatis也会创建一个resultMap实体类映射。 使用的时…

负载均衡算法深度探析:F5技术在高效流量管理中的应用

传统的单一服务器模式下&#xff0c;随着用户请求量的增加&#xff0c;单个服务器可能会承受过重的压力&#xff0c;导致响应速度下降甚至系统崩溃&#xff0c;负载均衡技术应运而生。它广泛应用于各种软硬件系统中&#xff0c;将网络流量以某种算法合理分配给各个节点&#xf…

【wiki知识库】05.分类管理实现--前端Vue模块

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;今日目标 二、&#x1f30f;前端部分的改造 2.1 新增一个tool.ts 2.2 新增admin-categoty.vue 2.3 添加新的路由规则 2.4 添加the-welcome.vue 2.5 修改HomeView.vue 三、❗注意 一、&…

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十六)- 微服务(6)

目录 10. Docker 10.1 Docker基本操作 10.1.1 镜像相关命令 10.1.2 容器相关命令 10.2 数据卷命令 10.2.1 常用命令 : 10.2.2 挂载数据卷 10. Docker 10.1 Docker基本操作 10.1.1 镜像相关命令 docker --help 查看docker帮助文档 docker images --help 查看docker ima…

人工智能任务5-高级算法工程师需要学习哪些课程与掌握哪些能力

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能的任务5-高级算法工程师需要学习哪些课程&#xff0c;需要掌握哪些能力。高级算法工程师需要掌握的算法模型有&#xff1a;人脸检测模型MTCNN&#xff0c;人脸识别方法Siamese network、center loss、softm…

你中了机房建设管理的这几个误区吗?

机房建设及管理中的六大误区 作为机房建设及运维管理人员&#xff0c;您是否也常因为以下问题面临各种“头痛”瞬间 —— 由于缺少支持材料以及分析文件&#xff0c;常常迫不得已成为了各类“网络问题”的最终“背锅侠”&#xff0c;不仅要面对来自领导和客户的压力&#xff0…

Java EE-Spring Security配置

Spring Security 基本概念 spring security 的核心功能主要包括&#xff1a; 认证 &#xff08;你是谁&#xff09; 授权 &#xff08;你能干什么&#xff09; 攻击防护 &#xff08;防止伪造身份&#xff09; 其核心就是一组过滤器链&#xff0c;项目启动后将会自动配置。…

多模态模型学会打扑克:表现超越GPT-4v,全新强化学习框架是关键

​卡奥斯智能交互引擎是卡奥斯基于海尔近40年工业生产经验积累和卡奥斯7年工业互联网平台建设的最佳实践&#xff0c;基于大语言模型和RAG技术&#xff0c;集合海量工业领域生态资源方优质产品和知识服务&#xff0c;旨在通过智能搜索、连续交互&#xff0c;实时生成个性化的内…

【计算机网络】计算机网络的概念

计算机网络的概念 导读一、计算机网络的概念1.1 个人理解1.2 通信设备与线路1.2.1 集线器1.2.2 交换机1.2.3 路由器 1.3 计算机网络的进一步理解1.4 互联网1.5 网的不同含义 二、计算机网络的不同定义2.1 广义观点2.2 资源共享观点2.3 用户透明性观点 结语 导读 大家好&#x…

JAVA小案例-用循环语句输出1-1000以内能被5整除的数,每5个一行

JAVA小案例-用循环语句输出1-1000以内能被5整除的数&#xff0c;每5个一行 直接看代码&#xff1a; public class Zhengchu {/*** 用循环语句输出1-1000以内能被5整除的数&#xff0c;每5个一行** param args*/public static void main(String[] args) {for (int i 1; i <…

拆分盘投资逻辑与风险探讨

一、引言 随着互联网金融的蓬勃发展&#xff0c;拆分盘作为一种新型投资模式逐渐进入公众视野。它以独特的“只涨不跌”的投资逻辑吸引了众多投资者的关注。本文将对拆分盘的投资逻辑进行解析&#xff0c;并通过一个简单示例进行说明&#xff0c;同时深入探讨其潜在风险&#…

【栈】736. Lisp 语法解析

本文涉及知识点 栈 LeetCode736. Lisp 语法解析 给你一个类似 Lisp 语句的字符串表达式 expression&#xff0c;求出其计算结果。 表达式语法如下所示: 表达式可以为整数&#xff0c;let 表达式&#xff0c;add 表达式&#xff0c;mult 表达式&#xff0c;或赋值的变量。表达…

软件需求分析文档(需求报告实际项目直接套用模板Word及软件全文档)

目录 第1章 序言 第2章 引言 2.1 项目概述 2.1.1 项目背景 2.1.2 项目目标 2.2 编写目的 2.3 文档约定 2.4 预期读者及阅读建议 第3章 技术要求 3.1 软件开发要求 3.1.1 接口要求 3.1.2 系统专有技术 3.1.3 查询功能 3.1.4 数据安全 3.1.5 可靠性要求 3.1.6 稳定…

Java面试题:解决Redis缓存击穿问题

缓存击穿 当一个key过期时,需要对这个key进行数据重建 在重建的时间内如果有大量的并发请求进入,就会绕过缓存进入数据库,会瞬间击垮DB 重建时间可能因为数据是多个表的混合结果需要分头统计而延长,从而更容易出现缓存击穿问题 缓存击穿的解决方案 添加互斥锁 先查询缓存…

随身WiFi十大热门品牌优缺点分析!哪个品牌的随身wifi更值得买?随身wifi推荐测评!

格行随身wifi 【品牌特点】&#xff1a;服务好&#xff0c;性价比高&#xff0c;随身WiFi行业的“海底捞” 【优点】&#xff1a;专注物联网行业15年&#xff0c;产品和服务双驱动&#xff0c;综合实力和客户口碑领先 【缺点】&#xff1a;产品相对聚焦&#xff0c;产品类型…