下载源码 https://github.com/baidu/uid-generator
新建springboot项目,pom文件如下:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.6.RELEASEversion>
<relativePath/>
parent>
<groupId>com.deliciousgroupId>
<artifactId>uid-generatorartifactId>
<version>1.0.0-SNAPSHOTversion>
<name>uid-generatorname>
<description>unique id generatordescription>
<properties>
<java.version>11java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>3.10version>
dependency>
dependencies>
project>
<dependency>
<groupId>com.deliciousgroupId>
<artifactId>uid-generatorartifactId>
<version>1.0.0-SNAPSHOTversion>
dependency>
DROP TABLE IF EXISTS worker_node_entity;
CREATE TABLE worker_node_entity
(
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 DATETIME NOT NULL COMMENT 'modified time',
CREATED DATETIME NOT NULL COMMENT 'created time',
PRIMARY KEY (ID)
)
COMMENT ='DB WorkerID Assigner for UID Generator', ENGINE = INNODB;
package com.delicious.litemall.mall.idGeneratorDao;
import com.baidu.fsg.uid.worker.entity.WorkerNodeEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author delicious
* @ClassName: WorkerNodeMapper
* @describe
* @createDate 2020/4/13
*/
public interface WorkerNodeMapper extends BaseMapper<WorkerNodeEntity> {
}
package com.delicious.litemall.mall.idGeneratorDao;
import com.baidu.fsg.uid.worker.dao.WorkerNodeDAO;
import com.baidu.fsg.uid.worker.entity.WorkerNodeEntity;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository;
import java.util.Date;
/**
* @author delicious
* @ClassName: WokerNodeDaoImpl
* @describe
* @createDate 2020/4/13
*/
@Repository
public class WorkerNodeDaoImpl
extends ServiceImpl<WorkerNodeMapper,WorkerNodeEntity>
implements WorkerNodeDAO {
@Override
public WorkerNodeEntity getWorkerNodeByHostPort(String host, String port) {
QueryWrapper<WorkerNodeEntity> wrapper = new QueryWrapper<WorkerNodeEntity>().eq("host", host).eq("port", port);
return super.getOne(wrapper);
}
@Override
public void addWorkerNode(WorkerNodeEntity workerNodeEntity) {
workerNodeEntity.setModified(new Date());
workerNodeEntity.setCreated(new Date());
super.save(workerNodeEntity);
}
}
/**
* Represents an implementation of {@link WorkerIdAssigner},
* the worker id will be discarded after assigned to the UidGenerator
*
* @author yutianbao
*/
@Component
public class DisposableWorkerIdAssigner implements WorkerIdAssigner {
private static final Logger LOGGER = LoggerFactory.getLogger(com.baidu.fsg.uid.worker.DisposableWorkerIdAssigner.class);
@Autowired
WorkerNodeDAO dao;
/**
* Assign worker id base on database.
* If there is host name & port in the environment, we considered that the node runs in Docker container
* Otherwise, the node runs on an actual machine.
*
* @return assigned worker id
*/
@Override
@Transactional
public long assignWorkerId() {
// build worker node entity
WorkerNodeEntity workerNodeEntity = buildWorkerNode();
// add worker node for new (ignore the same IP + PORT)
dao.addWorkerNode(workerNodeEntity);
LOGGER.info("Add worker node:" + workerNodeEntity);
return workerNodeEntity.getId();
}
/**
* Build worker node entity by IP and PORT
*/
private WorkerNodeEntity buildWorkerNode() {
WorkerNodeEntity workerNodeEntity = new WorkerNodeEntity();
if (DockerUtils.isDocker()) {
workerNodeEntity.setType(WorkerNodeType.CONTAINER.value());
workerNodeEntity.setHostName(DockerUtils.getDockerHost());
workerNodeEntity.setPort(DockerUtils.getDockerPort());
} else {
workerNodeEntity.setType(WorkerNodeType.ACTUAL.value());
workerNodeEntity.setHostName(NetUtils.getLocalAddress());
workerNodeEntity.setPort(System.currentTimeMillis() + "-" + RandomUtils.nextInt());
}
return workerNodeEntity;
}
}
@Configuration
public class CachedUidGeneratorConfig {
/**
* disposableWorkerIdAssigner的入参对象类型最好使用 WorkerIdAssigner,
* 否则其他地方引入CGLib动态代理的时候可能会导致代理混用的问题
*
* @param disposableWorkerIdAssigner
* @return
*/
@Bean
public DefaultUidGenerator defaultUidGenerator(WorkerIdAssigner disposableWorkerIdAssigner) {
DefaultUidGenerator defaultUidGenerator = new DefaultUidGenerator();
defaultUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner);
/**
* 关于UID比特分配的建议:
* 对于并发数要求不高、期望长期使用的应用, 可增加timeBits位数, 减少seqBits位数.
* 例如节点采取用完即弃的WorkerIdAssigner策略, 重启频率为12次/天, 那么配置成:
* {"workerBits":23,"timeBits":31,"seqBits":9}时, 可支持28个节点以整体并发量14400 UID/s的速度持续运行68年.
*
* 对于节点重启频率频繁、期望长期使用的应用, 可增加workerBits和timeBits位数, 减少seqBits位数.
* 例如节点采取用完即弃的WorkerIdAssigner策略, 重启频率为24*12次/天, 那么配置成:
* {"workerBits":27,"timeBits":30,"seqBits":6}时, 可支持37个节点以整体并发量2400 UID/s的速度持续运行34年.
*/
//以下为可选配置, 如未指定将采用默认值
defaultUidGenerator.setTimeBits(32);
// 机器id,最多可支持2^22约420w次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃,后续可提供复用策略。
defaultUidGenerator.setWorkerBits(22);
// 每秒下的并发序列,9 bits可支持每台服务器每秒512个并发。
defaultUidGenerator.setSeqBits(9);
defaultUidGenerator.setEpochStr("2020-01-01");
return defaultUidGenerator;
}
/**
* disposableWorkerIdAssigner的入参对象类型最好使用 WorkerIdAssigner,
* 否则其他地方引入CGLib动态代理的时候可能会导致代理混用的问题
*
* @param disposableWorkerIdAssigner
* @return
*/
@Bean
public CachedUidGenerator cachedUidGenerator(WorkerIdAssigner disposableWorkerIdAssigner) {
CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
cachedUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner);
/**
* 关于UID比特分配的建议:
* 对于并发数要求不高、期望长期使用的应用, 可增加timeBits位数, 减少seqBits位数.
* 例如节点采取用完即弃的WorkerIdAssigner策略, 重启频率为12次/天, 那么配置成:
* {"workerBits":23,"timeBits":31,"seqBits":9}时, 可支持28个节点以整体并发量14400 UID/s的速度持续运行68年.
*
* 对于节点重启频率频繁、期望长期使用的应用, 可增加workerBits和timeBits位数, 减少seqBits位数.
* 例如节点采取用完即弃的WorkerIdAssigner策略, 重启频率为24*12次/天, 那么配置成:
* {"workerBits":27,"timeBits":30,"seqBits":6}时, 可支持37个节点以整体并发量2400 UID/s的速度持续运行34年.
*/
//以下为可选配置, 如未指定将采用默认值
cachedUidGenerator.setTimeBits(32);
// 机器id,最多可支持2^22约420w次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃,后续可提供复用策略。
cachedUidGenerator.setWorkerBits(22);
// 每秒下的并发序列,9 bits可支持每台服务器每秒512个并发。
cachedUidGenerator.setSeqBits(9);
cachedUidGenerator.setEpochStr("2020-01-01");
//RingBuffer size扩容参数, 可提高UID生成的吞吐量
//默认:3, 原bufferSize=8192, 扩容后bufferSize= 8192 << 3 = 65536
cachedUidGenerator.setBoostPower(3);
// 指定何时向RingBuffer中填充UID, 取值为百分比(0, 100), 默认为50
// 举例: bufferSize=1024, paddingFactor=50 -> threshold=1024 * 50 / 100 = 512.
// 当环上可用UID数量 < 512时, 将自动对RingBuffer进行填充补全
//
//另外一种RingBuffer填充时机, 在Schedule线程中, 周期性检查填充
//默认:不配置此项, 即不实用Schedule线程. 如需使用, 请指定Schedule线程时间间隔, 单位:秒
cachedUidGenerator.setScheduleInterval(60L);
//拒绝策略: 当环已满, 无法继续填充时
//默认无需指定, 将丢弃Put操作, 仅日志记录. 如有特殊需求, 请实现RejectedPutBufferHandler接口(支持Lambda表达式)
//
//cachedUidGenerator.setRejectedPutBufferHandler();
//拒绝策略: 当环已空, 无法继续获取时 -->
//默认无需指定, 将记录日志, 并抛出UidGenerateException异常. 如有特殊需求, 请实现RejectedTakeBufferHandler接口(支持Lambda表达式) -->
//
return cachedUidGenerator;
}
}
@Autowired
CachedUidGenerator cachedUidGenerator;
@Test
public void uidTest2(){
for (int i=0;i<10;i++){
System.out.println(cachedUidGenerator.getUID());
}
}
输出结果:
总结
使用springboot整合了uidGenerator,使用mybatisplus代替了mybatis。