百度开源的分布式 ID 生成器,太强大了!

沙海 2021年5月29日07:04:08Java评论49字数 7942阅读26分28秒阅读模式
摘要

速读摘要

速读摘要文章源自JAVA秀-https://www.javaxiu.com/27320.html

一般在项目搭建过程中,springboot中已经有了logback依赖,mybatis会作为单独的依赖引入。如果版本和uid-generator中的依赖不一致的话,就会导致冲突。欢迎加入我的知识星球,一起探讨架构,交流源码。MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。文章源自JAVA秀-https://www.javaxiu.com/27320.html

原文约 5124 | 图片 8 | 建议阅读 11 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!

点击关注 ? 芋道源码 文章源自JAVA秀-https://www.javaxiu.com/27320.html

收录于话题文章源自JAVA秀-https://www.javaxiu.com/27320.html

#芋道源码文章源自JAVA秀-https://www.javaxiu.com/27320.html

94个文章源自JAVA秀-https://www.javaxiu.com/27320.html

点击上方“芋道源码”,选择“设为星标文章源自JAVA秀-https://www.javaxiu.com/27320.html

管她前浪,还是后浪?文章源自JAVA秀-https://www.javaxiu.com/27320.html

能浪的浪,才是好浪!文章源自JAVA秀-https://www.javaxiu.com/27320.html

每天 8:55 更新文章,每天掉亿点点头发...文章源自JAVA秀-https://www.javaxiu.com/27320.html

文章源自JAVA秀-https://www.javaxiu.com/27320.html

源码精品专栏文章源自JAVA秀-https://www.javaxiu.com/27320.html

 文章源自JAVA秀-https://www.javaxiu.com/27320.html

文章源自JAVA秀-https://www.javaxiu.com/27320.html

来源:lilinchao.com/archives/1226.html文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!文章源自JAVA秀-https://www.javaxiu.com/27320.html

一、UidGenerator是什么

UidGenerator是百度开源的一款分布式高性能的唯一ID生成器,是基于snowflake模型的一种ID生成器文章源自JAVA秀-https://www.javaxiu.com/27320.html

二、UidGenerator的优势

1.解决了时钟回调的问题文章源自JAVA秀-https://www.javaxiu.com/27320.html

2.使用ringbuffer,无锁进行id的生产与消费,速度非常快文章源自JAVA秀-https://www.javaxiu.com/27320.html

3.适用于多线程,不会有单线程瓶颈文章源自JAVA秀-https://www.javaxiu.com/27320.html

三、整合

本次通过SpringBoot2.x和MyBatis对百度UidGenerator进行整合。文章源自JAVA秀-https://www.javaxiu.com/27320.html

3.1 UidGenerator引入

一般使用两种方式引入UidGenerator:文章源自JAVA秀-https://www.javaxiu.com/27320.html

(1)从官网下载源码作为自己项目的一个Module引入到项目中文章源自JAVA秀-https://www.javaxiu.com/27320.html

官网地址:https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md文章源自JAVA秀-https://www.javaxiu.com/27320.html

(2)互联网jar包引入(本文采取的是该种方式)文章源自JAVA秀-https://www.javaxiu.com/27320.html

因为UidGenerator自带引入了mybatis,和自己项目有冲突的可以进行排除文章源自JAVA秀-https://www.javaxiu.com/27320.html

<dependency>    <groupId>com.xfvape.uid</groupId>    <artifactId>uid-generator</artifactId>    <version>0.0.4-RELEASE</version></dependency>

排除冲突依赖文章源自JAVA秀-https://www.javaxiu.com/27320.html

uid-generator中依赖了logback和mybatis。一般在项目搭建过程中,springboot中已经有了logback依赖,mybatis会作为单独的依赖引入。如果版本和uid-generator中的依赖不一致的话,就会导致冲突。文章源自JAVA秀-https://www.javaxiu.com/27320.html

排除冲突的依赖如下:文章源自JAVA秀-https://www.javaxiu.com/27320.html

<dependency>    <groupId>com.xfvape.uid</groupId>    <artifactId>uid-generator</artifactId>    <version>0.0.4-RELEASE</version>    <exclusions>                <exclusion>                    <groupId>org.slf4j</groupId>                    <artifactId>log4j-over-slf4j</artifactId>                </exclusion>                <exclusion>                    <groupId>ch.qos.logback</groupId>                    <artifactId>logback-classic</artifactId>                </exclusion>                <exclusion>                    <groupId>org.slf4j</groupId>                    <artifactId>slf4j-api</artifactId>                </exclusion>                 <exclusion>                    <groupId>org.mybatis</groupId>                    <artifactId>mybatis-spring</artifactId>                </exclusion>                <exclusion>                    <groupId>org.mybatis</groupId>                    <artifactId>mybatis</artifactId>                </exclusion>    </exclusions></dependency>

3.2 创建表

在 MySQL数据库中建一个名为 WORKER_NODE的数据表,其 sql如下:文章源自JAVA秀-https://www.javaxiu.com/27320.html

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;

建表时可能会报错,原因是该建表语句定义了两个TIMESTAMP字段,因为mysql 低版本控制比较严格文章源自JAVA秀-https://www.javaxiu.com/27320.html

解决办法:文章源自JAVA秀-https://www.javaxiu.com/27320.html

方式一:文章源自JAVA秀-https://www.javaxiu.com/27320.html

直接把TIMESTAMP改成DATETIME 即可文章源自JAVA秀-https://www.javaxiu.com/27320.html

方式二:文章源自JAVA秀-https://www.javaxiu.com/27320.html

建表前先设置sql_mode:文章源自JAVA秀-https://www.javaxiu.com/27320.html

set sql_mode="NO_ENGINE_SUBSTITUTION";

3.3 将uid-generator核心对象装配为spring的bean

uid-generator提供了两种生成器: DefaultUidGenerator、CachedUidGenerator。如对UID生成性能有要求, 请使用CachedUidGenerator。文章源自JAVA秀-https://www.javaxiu.com/27320.html

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

直接创建WorkerNodeConfig类,复制以上代码。文章源自JAVA秀-https://www.javaxiu.com/27320.html

3.4 重写WorkerIdAssigner接口

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;    }}

创建一个DisposableWorkerIdAssigner类直接复制以上代码。文章源自JAVA秀-https://www.javaxiu.com/27320.html

3.5 引入WorkerNodeMapper.xml

<?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.uidgenerator.mapper.WorkerNodeMapper">  <resultMap id="BaseResultMap"             type="com.uidgenerator.entity.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.uidgenerator.entity.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>

可以通过mybatis生成工具直接生成文件和实体类,然后将插入和查询方法复制文章源自JAVA秀-https://www.javaxiu.com/27320.html

注意修改resultMap中的type和insert中的keyProperty为自身项目的实体类地址文章源自JAVA秀-https://www.javaxiu.com/27320.html

在application.yml文件中增加如下配置文章源自JAVA秀-https://www.javaxiu.com/27320.html

mybatis:  mapper-locations: classpath:mybatis/*.xml

3.6实体类

使用插件生成的实体类文章源自JAVA秀-https://www.javaxiu.com/27320.html

3.7创建Mapper

@Mapperpublic interface WorkerNodeMapper {    int addWorkerNode(WorkerNode workerNodeEntity);    WorkerNode getWorkerNodeByHostPort(@Param("host") String host, @Param("port") String port);}

3.8 Service

IWorkerNodeService接口文章源自JAVA秀-https://www.javaxiu.com/27320.html

public interface IWorkerNodeService {    public long genUid();}

WorkerNodeServiceImpl实现类文章源自JAVA秀-https://www.javaxiu.com/27320.html

@Servicepublic class WorkerNodeServiceImpl implements IWorkerNodeService {    @Resource    private UidGenerator uidGenerator;    @Override    public long genUid() {        Long uu_id = UidGeneratorComponent.uu_id;        return uidGenerator.getUID();    }}

3.8 Controller

@RestControllerpublic class WorkerNodeServiceController {    @Resource    private IWorkerNodeService workerNodeService;    /**     * 集成百度uid-generator生成id     * @return     */    @GetMapping("/baidu/uid")    public long baiduUid(){        long uid = workerNodeService.genUid();        return uid;    }}

3.9 访问接口测试

http://127.0.0.1:8099/test/baidu/uid文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!文章源自JAVA秀-https://www.javaxiu.com/27320.html

项目目录结构文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!文章源自JAVA秀-https://www.javaxiu.com/27320.html

欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!文章源自JAVA秀-https://www.javaxiu.com/27320.html

已在知识星球更新源码解析如下:文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!文章源自JAVA秀-https://www.javaxiu.com/27320.html

百度开源的分布式 ID 生成器,太强大了!文章源自JAVA秀-https://www.javaxiu.com/27320.html

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。文章源自JAVA秀-https://www.javaxiu.com/27320.html

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。文章源自JAVA秀-https://www.javaxiu.com/27320.html

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。文章源自JAVA秀-https://www.javaxiu.com/27320.html

文章源自JAVA秀-https://www.javaxiu.com/27320.html

文章有帮助的话,在看,转发吧。谢谢支持哟 (*^__^*)
文章源自JAVA秀-https://www.javaxiu.com/27320.html

阅读原文文章源自JAVA秀-https://www.javaxiu.com/27320.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定