Skip to content

分布式id生成器,根据百度uid开源项目封装;易于集成、易于使用、可回收worker等特点

Notifications You must be signed in to change notification settings

c-s-t-z/uid-generator-spring-boot-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

分布式id生成器

原理

基于百度UidGenerator封装,百度UidGenerator 参考 需要在spring环境下使用

特点

引入依赖后使用注解启用分布式id生成器,在需要分布式id的地方注入UidGenerator即可; 其中有两种workerid使用模式:一种是基于百度UidGenerator原生一次性;一种是可回收的id,基于启动时间和复用率平衡,在极端配置下可以做到百分百复用率;

其中可回收模式原理:

启动时获取retry个没有续约的worker信息:存在以下几种场景

1 没有获取到,也就是所有worker都在使用;直接插入一个新的worker;
2 获取到了,经过乐观锁检测当前服务竞争成功,获取到了当前没有续约的worker的使用权,当前服务使用这个workerid并更新相关worker数据
3 获取到了,经过retry次的乐观锁检测没有竞争成功,直接插入一个新的worker;

启动成功,会根据renewal-frequency-hours属性,定期续约;

依赖

commons-lang3:3.17.0

mybatis-spring-boot-starter:2.3.2

spring-boot:2.6.13

jdk1.8

img.png

使用

步骤1

在github上将本项目下载,然后直接在根目录执行 mvn clean package -Dmaven.test.skip=true;

步骤2

本地环境

将该jar包发布到本地maven仓库中;

mvn install:install-file -Dfile=/绝对路径/uid-generator-spring-boot-starter-1.0.0.jar  -DgroupId=com.hhsj.uid.generator  -DartifactId=uid-generator-spring-boot-starter -Dversion=1.0.0 -Dpackaging=jar

测试环境 预发环境 生产环境

将该jar包上传到公司maven私服中,这样在构建项目编译项目时都可以引用到该依赖;

使用定制化的maven配置(如果有的话 没有的话不用指定maven配置文件) 编译 发布该项目
mvn -s D:\apache-maven-3.6.3\conf\settings-定制化.xml deploy:deploy-file -Dfile=.\uid-generator-spring-boot-starter-1.0.0.jar -DpomFile=.\uid-generator-spring-boot-starter-1.0.0.pom -Dpackaging=jar -DgroupId=com.hhsj.uid.generator  -DartifactId=uid-generator-spring-boot-starter -Dversion=1.0.0 -Durl=http://htyy.com/repository/maven-releases -DrepositoryId=private-htyy-nexus

参考

步骤3

在你需要使用分布式id的项目中引入这个依赖;

            <dependency>
                <groupId>com.hhsj.uid.generator</groupId>
                <artifactId>uid-generator-spring-boot-starter</artifactId>
                <version>1.0.0</version>
            </dependency>

步骤4

在启动类上增加@EnableUidGenerator注解

mode 指定使用的生成器模式 默认值UidGeneratorModeEnum.DEFAULT_MODE; 
    一种是使用预生成方式提高性能(CachedUidGenerator) 
    一种是直接生成方式(DefaultUidGenerator);

workerIdMode 指定workerId回收模式 默认值WorkerIdModeEnum.RECYCLABLE_MODE;
    一种是基于百度UidGenerator原生一次性;
    一种是可回收的id,基于启动时间和复用率平衡,在极端配置下可以做到百分百复用率;

配置分布式id相关属性;

uid:
    generator:
        renewal-frequency-hours: 续约周期单位小时 默认168小时
        datasource:
            driver-class-name: com.mysql.cj.jdbc.Driver
            jdbc-url: 分数缓存也需要使用的数据库地址
            username: 用户名
            password: 密码
        time-bits: 时间位数 默认28
        worker-bits: 机器位数
        seq-bits: 并发序列号位数
        epoch-str: epoch时间 默认值2025-04-15
        retry: 重试次数 如果workerId回收模式是WorkerIdModeEnum.RECYCLABLE_MODE,可以配置大于等于0的重试次数

步骤5

如果你的项目涉及到数据库操作,需要配置一下数据源,可以参考


@Configuration
@MapperScan(basePackages = "com.bbg.hhsj.htyy.gatewayimpl.database", sqlSessionFactoryRef = "sqlSessionFactoryPrimary")
public class DataBaseSourceConfiguration {


    @Bean(name = "dataSourcePrimary")
    @ConfigurationProperties(prefix = "spring.datasource.druid.primary")
    public DataSource dataSourceView() {
        return DruidDataSourceBuilder.create().build();
    }
    @Bean(name = "sqlSessionFactoryPrimary")
    public SqlSessionFactory sqlSessionFactoryView(@Qualifier("dataSourcePrimary") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/*.xml"));
        sessionFactory.setTypeAliasesPackage("com.bbg.hhsj.htyy.gatewayimpl.database.dataobject");
        sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
        return sessionFactory.getObject();
    }
    @Bean(name = "sqlSessionTemplateView")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactoryPrimary") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean(name = "transactionManagerPrimary")
    public PlatformTransactionManager transactionManagerView(@Qualifier("dataSourcePrimary") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

步骤6

直接创建表sql WorkerNode.sql

事例

配置 参考步骤4和步骤5

@Component
public class LocalAsyncOneCmdExe {
    private final UidGenerator uidGenerator;
    private final CommonDomainGateway commonDomainGateway;
    
    public String createData(LocalAsyncOneCmd localAsyncOneCmd) {
        long uid = uidGenerator.getUID();
        System.out.println("uid   =====   " + uid);
        int data = commonDomainGateway.createData(uid+"");
        return data + "";
    }
}

ideas&tips

可以将获取worker id的操作单独拆分出去,使用rpc等方式处理,使项目的DB层解耦;

其他更好的想法大家可以直接提,我会抓时间处理;

bug欢迎大家提出来或者直接PR;

注意

我在项目中进行了基础测试,如果大家遇到什么问题欢迎大家提出来;本人只是站在巨人的肩膀上进行了易集成、易接入、易使用的封装;

大家在接入时请充分测试;

About

分布式id生成器,根据百度uid开源项目封装;易于集成、易于使用、可回收worker等特点

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages