共计 5710 个字符,预计需要花费 15 分钟才能阅读完成。
起源:https://lilinchao.com/archive…
一、UidGenerator 是什么
UidGenerator 是百度开源的一款分布式高性能的惟一 ID 生成器,是基于 snowflake 模型的一种 ID 生成器
二、UidGenerator 的劣势
- 解决了时钟回调的问题
- 应用 ringbuffer, 无锁进行 id 的生产与生产, 速度十分快
- 实用于多线程, 不会有单线程瓶颈
三、整合
本次通过 SpringBoot2.x 和 MyBatis 对百度 UidGenerator 进行整合。
3.1 UidGenerator 引入
个别应用两种形式引入 UidGenerator:
1)从官网下载源码作为本人我的项目的一个 Module 引入到我的项目中
官网地址:https://github.com/baidu/uid-…
2)互联网 jar 包引入(本文采取的是该种形式)
因为 UidGenerator 自带引入了 mybatis,和本人我的项目有抵触的能够进行排除
<dependency> | |
<groupId>com.xfvape.uid</groupId> | |
<artifactId>uid-generator</artifactId> | |
<version>0.0.4-RELEASE</version> | |
</dependency> |
排除抵触依赖
uid-generator 中依赖了 logback 和 mybatis。个别在我的项目搭建过程中,springboot 中曾经有了 logback 依赖,mybatis 会作为独自的依赖引入。如果版本和 uid-generator 中的依赖不统一的话,就会导致抵触。
排除抵触的依赖如下:
<dependency> | |
<groupId>com.xfvape.uid</groupId> | |
<artifactId>uid-generator</artifactId> | |
<version>0.0.4-RELEASE</version> | |
<exclusions> | |
<exclusion> | |
<groupId>org.slf4j</groupId> | |
<artifactId>log4j-over-slf4j</artifactId> | |
</exclusion> | |
<exclusion> | |
<groupId>ch.qos.logback</groupId> | |
<artifactId>logback-classic</artifactId> | |
</exclusion> | |
<exclusion> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-api</artifactId> | |
</exclusion> | |
<exclusion> | |
<groupId>org.mybatis</groupId> | |
<artifactId>mybatis-spring</artifactId> | |
</exclusion> | |
<exclusion> | |
<groupId>org.mybatis</groupId> | |
<artifactId>mybatis</artifactId> | |
</exclusion> | |
</exclusions> | |
</dependency> |
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"?> | |
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
<mapper namespace="com.uidgenerator.mapper.WorkerNodeMapper"> | |
<resultMap id="BaseResultMap" | |
type="com.uidgenerator.entity.WorkerNode"> | |
<id column="ID" jdbcType="BIGINT" property="id" /> | |
<result column="HOST_NAME" jdbcType="VARCHAR" property="hostName" /> | |
<result column="PORT" jdbcType="VARCHAR" property="port" /> | |
<result column="TYPE" jdbcType="INTEGER" property="type" /> | |
<result column="LAUNCH_DATE" jdbcType="DATE" property="launchDate" /> | |
<result column="MODIFIED" jdbcType="TIMESTAMP" property="modified" /> | |
<result column="CREATED" jdbcType="TIMESTAMP" property="created" /> | |
</resultMap> | |
<insert id="addWorkerNode" useGeneratedKeys="true" keyProperty="id" | |
parameterType="com.uidgenerator.entity.WorkerNode"> | |
INSERT INTO WORKER_NODE | |
(HOST_NAME, | |
PORT, | |
TYPE, | |
LAUNCH_DATE, | |
MODIFIED, | |
CREATED) | |
VALUES (#{hostName}, | |
#{port}, | |
#{type}, | |
#{launchDate}, | |
NOW(), | |
NOW()) | |
</insert> | |
<select id="getWorkerNodeByHostPort" resultMap="BaseResultMap"> | |
SELECT | |
ID, | |
HOST_NAME, | |
PORT, | |
TYPE, | |
LAUNCH_DATE, | |
MODIFIED, | |
CREATED | |
FROM | |
WORKER_NODE | |
WHERE | |
HOST_NAME = #{host} AND PORT = #{port} | |
</select> | |
</mapper> |
能够通过 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/ba…
我的项目目录构造
近期热文举荐:
1.600+ 道 Java 面试题及答案整顿 (2021 最新版)
2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!
3. 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!
4.Spring Cloud 2020.0.0 正式公布,全新颠覆性版本!
5.《Java 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!