1 Star 2 Fork 11

guoweixin/uid-generator-springboot

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

uid-generator-springboot

介绍

基于分布式id 百度开源UidGenerator整合SpringBoot案例 UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。

参考视频: https://www.bilibili.com/video/BV1CL411778r?p=82

分布式ID

应用场景

	在业务系统中很多场景下需要生成不重复的 ID,比如京东订单编号、飞机票订单号、外卖订单号、支付流水单号、优惠券编号等都需要使用到。账户进行标识,以一个有意义的有序的序列号来作为全局唯一的ID。

以京东为例,为了保证(用户信息安全),可通过订单编号查询到:商家信息、买家信息、物流信息、等关联全部信息。

输入图片说明

分布式ID特点

分布式系统中我们对ID生成器要求又有哪些呢?

1. 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。
2. 简洁/直观:(生成的ID号)客户用于关联其它业务的唯一重要凭证。
3. 高并发
4. 高性能
5. 高可用

系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。

解决方案

1. 基于数据库方案

2. UUID

3. Redis生成ID

4. Twitter的snowflake算法

5. 利用zookeeper生成唯一ID

分布式解决方案描述

SnowFlake算法

	snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。
	官方代码:https://github.com/twitter/snowflake。雪花算法支持的TPS可以达到419万左右(2^22*1000)。

雪花算法在工程实现上有单机版本和分布式版本。单机版本如下,
	分布式版本可以参看美团leaf算法:https://github.com/Meituan-Dianping/Leaf
	百度封装并开源:uid-generator https://github.com/baidu/uid-generator

百度uid-generator

唯一ID生成器

	UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于docker等虚拟化环境下实例自动重启、漂移等场景。
    在实现上, UidGenerator通过借用未来时间来解决sequence天然存在的并发限制; 采用RingBuffer来缓存已生成的UID, 并行化UID的生产和消费, 同时对CacheLine补齐,避免了由RingBuffer带来的硬件级「伪共享」问题.
    最终单机QPS可达600万。依赖版本:Java8及以上版本, MySQL(内置WorkerID分配器, 启动阶段通过DB进行分配; 如自定义实现, 则DB非必选依赖)

中文文档

https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md

官方源码

https://github.com/baidu/uid-generator

代码实战

架构如下依次创建

chapter-disributed-id  父工程(pom)
  uid-generator  jar(普通jar)
  boot-disributed-id  jar[8080]微服务 SSM操作

MySQL创建表WORKER_NODE

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;

官方源码下载

https://github.com/baidu/uid-generator/

创建uid-generator 普通jar 子工程

输入图片说明

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>chapter-distributed-id</artifactId>
        <groupId>com.qfjy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>uid-generator</artifactId>

    <name>uid-generator</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>


    <!-- Properties -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jdk.version>1.8</jdk.version>
        <spring.version>4.2.5.RELEASE</spring.version>
        <slf4j-version>1.7.7</slf4j-version>
    </properties>

    <dependencies>
		<!--父工程  springboot已继续 spring web/mybatis相关ar -->
        <!-- Apache Commons -->
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.2</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>
</project>

创建微服务子工程boot-disributed-id

SpringBoot SSM整合(此处忽略)

导入上方支持依赖jar

  <!-- 工具类包  uid-generator jar 包 -->
        <dependency>
            <groupId>com.qfjy</groupId>
            <artifactId>uid-generator</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

输入图片说明

配置生成器 cached-uid-spring.xml

提供了两种生成器: DefaultUidGeneratorCachedUidGenerator

如对UID生成性能有要求, 请使用CachedUidGenerator 对应Spring配置分别为: default-uid-spring.xmlcached-uid-spring.xml

CachedUidGenerator配置

项目资源包路径下创建uid文件夹,然后到官方uid-generator 测试 [注意:这里是测试资源包] 资源包路径下uid/cached-uid-spring.xml 复制cached-uid-spring.xml文件,粘贴到该文件夹uid内。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

    <!-- UID generator -->
    <bean id="disposableWorkerIdAssigner" class="com.baidu.fsg.uid.worker.DisposableWorkerIdAssigner" />

    <bean id="cachedUidGenerator" class="com.baidu.fsg.uid.impl.CachedUidGenerator">
        <property name="workerIdAssigner" ref="disposableWorkerIdAssigner" />
        <property name="epochStr" value="2020-03-17"/>
        <!-- 以下为可选配置, 如未指定将采用默认值 -->
        <!-- RingBuffer size扩容参数, 可提高UID生成的吞吐量. -->
        <!-- 默认:3, 原bufferSize=8192, 扩容后bufferSize= 8192 << 3 = 65536 -->
        <!--<property name="boostPower" value="3"></property>-->

        <!-- 指定何时向RingBuffer中填充UID, 取值为百分比(0, 100), 默认为50 -->
        <!-- 举例: bufferSize=1024, paddingFactor=50 -> threshold=1024 * 50 / 100 = 512. -->
        <!-- 当环上可用UID数量 < 512时, 将自动对RingBuffer进行填充补全 -->
        <!--<property name="paddingFactor" value="50"></property>-->

        <!-- 另外一种RingBuffer填充时机, 在Schedule线程中, 周期性检查填充 -->
        <!-- 默认:不配置此项, 即不实用Schedule线程. 如需使用, 请指定Schedule线程时间间隔, 单位:秒 -->
        <!--<property name="scheduleInterval" value="60"></property>-->

        <!-- 拒绝策略: 当环已满, 无法继续填充时 -->
        <!-- 默认无需指定, 将丢弃Put操作, 仅日志记录. 如有特殊需求, 请实现RejectedPutBufferHandler接口(支持Lambda表达式) -->
        <!--<property name="rejectedPutBufferHandler" ref="XxxxYourPutRejectPolicy"></property>-->
        <!-- 拒绝策略: 当环已空, 无法继续获取时 -->
        <!-- 默认无需指定, 将记录日志, 并抛出UidGenerateException异常. 如有特殊需求, 请实现RejectedTakeBufferHandler接口(支持Lambda表达式) -->
        <!--<property name="rejectedPutBufferHandler" ref="XxxxYourPutRejectPolicy"></property>-->
    </bean>
</beans>

创建配置UidConfig

package com.qfjy.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
/**
 * @ClassName UidConfig
 * @Description TODO
 * @Author guoweixin
 * @Version 1.0
 */
@Configuration
//导入外部XML配置文件
@ImportResource(locations = { "classpath:uid/cached-uid-spring.xml" })
public class UidConfig {
}

入口类

@SpringBootApplication
@MapperScan(basePackages = {"com.baidu.fsg.uid"})  /("com.baidu.fsg.uid")扫描到工具类Mapper类
public class BootDistributedIdApplication {
    public static void main(String[] args) {
        SpringApplication.run(BootDistributedIdApplication.class, args);
    }
}

测试

@SpringBootTest
@Slf4j
class BootDistributedIdApplicationTests {

    @Resource(name="cachedUidGenerator")
    private UidGenerator uidGenerator;
    @Test
    void contextLoads() {
        log.info("开始--->");
            System.out.println(uidGenerator.getUID());
        log.info("----->结束---->");
    }
}

输入图片说明

方案总结

​ 实际业务中,除了分布式ID全局唯一之外,还有是否趋势/连续递增的要求。根据具体业务需求的不同,有两种可选方案。

​ 一是只保证全局唯一,不保证连续递增。二是既保证全局唯一,又保证连续递增。

空文件

简介

基于分布式id 百度开源UidGenerator整合SpringBoot案例 UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。 展开 收起
取消

发行版

暂无发行版

贡献者

全部

语言

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/guoweixin/uid-generator-springboot.git
git@gitee.com:guoweixin/uid-generator-springboot.git
guoweixin
uid-generator-springboot
uid-generator-springboot
master

搜索帮助