SpringBoot2。x整合百度UidGenerator
一、UidGenerator是什么
UidGenerator是百度开源的一款分布式高性能的唯一ID生成器,是基于snowflake模型的一种ID生成器二、UidGenerator的优势1.解决了时钟回调的问题
2.使用ringbuffer,无锁进行id的生产与消费,速度非常快
3.适用于多线程,不会有单线程瓶颈三、整合
本次通过SpringBoot2.x和MyBatis对百度UidGenerator进行整合。
3.1 UidGenerator引入
一般使用两种方式引入UidGenerator:
(1)从官网下载源码作为自己项目的一个Module引入到项目中
官网地址:github.com/baidu/uid-g…
(2)互联网jar包引入(本文采取的是该种方式)
因为UidGenerator自带引入了mybatis,和自己项目有冲突的可以进行排除 com.xfvape.uid uid-generator 0.0.4-RELEASE
排除冲突依赖
uid-generator中依赖了logback和mybatis。一般在项目搭建过程中,springboot中已经有了logback依赖,mybatis会作为单独的依赖引入。如果版本和uid-generator中的依赖不一致的话,就会导致冲突。
排除冲突的依赖如下: com.xfvape.uid uid-generator 0.0.4-RELEASE org.slf4j log4j-over-slf4j ch.qos.logback logback-classic org.slf4j slf4j-api org.mybatis mybatis-spring org.mybatis mybatis
3.2 创建表
在 MySQL数据库中建一个名为 WORKER_NODE的数据表,其 sql如下: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 低版本控制比较严格
解决办法:
方式一:
直接把TIMESTAMP改成DATETIME 即可
方式二:
建表前先设置sql_mode:set sql_mode="NO_ENGINE_SUBSTITUTION";
3.3 将uid-generator核心对象装配为spring的bean
uid-generator提供了两种生成器: DefaultUidGenerator、CachedUidGenerator。如对UID生成性能有要求, 请使用CachedUidGenerator。@Configuration public 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类,复制以上代码。
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类直接复制以上代码。
3.5 引入WorkerNodeMapper.xml<?xml version="1.0" encoding="UTF-8"?> INSERT INTO WORKER_NODE (HOST_NAME, PORT, TYPE, LAUNCH_DATE, MODIFIED, CREATED) VALUES ( #{hostName}, #{port}, #{type}, #{launchDate}, NOW(), NOW())
可以通过mybatis生成工具直接生成文件和实体类,然后将插入和查询方法复制
注意修改resultMap中的type和insert中的keyProperty为自身项目的实体类地址
在application.yml文件中增加如下配置mybatis: mapper-locations: classpath:mybatis/*.xml
3.6实体类
使用插件生成的实体类
3.7创建Mapper@Mapper public interface WorkerNodeMapper { int addWorkerNode(WorkerNode workerNodeEntity); WorkerNode getWorkerNodeByHostPort(@Param("host") String host, @Param("port") String port); }
3.8 Service
IWorkerNodeService接口public interface IWorkerNodeService { public long genUid(); }
WorkerNodeServiceImpl实现类@Service public class WorkerNodeServiceImpl implements IWorkerNodeService { @Resource private UidGenerator uidGenerator; @Override public long genUid() { Long uu_id = UidGeneratorComponent.uu_id; return uidGenerator.getUID(); } }
3.8 Controller@RestController public 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
项目目录结构