基于百度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
在github上将本项目下载,然后直接在根目录执行 mvn clean package -Dmaven.test.skip=true;
将该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
在你需要使用分布式id的项目中引入这个依赖;
<dependency>
<groupId>com.hhsj.uid.generator</groupId>
<artifactId>uid-generator-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
在启动类上增加@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的重试次数
如果你的项目涉及到数据库操作,需要配置一下数据源,可以参考
@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);
}
}
直接创建表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 + "";
}
}
可以将获取worker id的操作单独拆分出去,使用rpc等方式处理,使项目的DB层解耦;
其他更好的想法大家可以直接提,我会抓时间处理;
bug欢迎大家提出来或者直接PR;
我在项目中进行了基础测试,如果大家遇到什么问题欢迎大家提出来;本人只是站在巨人的肩膀上进行了易集成、易接入、易使用的封装;
大家在接入时请充分测试;