简介
uid-generator是由百度技术部开发,项目GitHub地址 https://github.com/baidu/uid-generator
UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。
Snowflake算法
Snowflake算法描述:指定机器 & 同一时刻 & 某一并发序列,是唯一的。据此可生成一个64 bits的唯一ID(long)。默认采用上图字节分配方式:
-
sign(1bit)
固定1bit符号标识,即生成的UID为正数。 -
delta seconds (28 bits)
当前时间,相对于时间基点"2016-05-20"的增量值,单位:秒,最多可支持约8.7年 -
worker id (22 bits)
机器id,最多可支持约420w次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃,后续可提供复用策略。 -
sequence (13 bits)
每秒下的并发序列,13 bits可支持每秒8192个并发。
集成步骤
官方文档上的集成教程都是基于Spring + Mybatis XML配置的,不适用于SpringBoot,所以自己做了一些改造。
1. 将项目导入本地环境,执行maven install
2. 创建数据表
DROP TABLE IF EXISTS WORKER_NODE;
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;
3. 项目中引入uid-generator依赖,并排除其中的mybatis依赖
由于自己的项目是SpringBoot+Mybatisplus,UidGenerator是Spring+Mybatis,直接引入uid-generator之后,本地项目启动就会出现创建SqlSessionFactory报错,所以,我直接将uid-generator中的mybatis相关依赖排除。
<dependency>
<groupId>com.baidu.fsg</groupId>
<artifactId>uid-generator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
4. 利用代码生成工具,将worker_node对应的代码生成,并拷贝相关源码
将源码中的xml中的方法拷贝到自己的xml文件中:
<resultMap id="workerNodeRes"
type="com.example.mybatisplus.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.example.mybatisplus.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="workerNodeRes">
SELECT
ID,
HOST_NAME,
PORT,
TYPE,
LAUNCH_DATE,
MODIFIED,
CREATED
FROM
WORKER_NODE
WHERE
HOST_NAME = #{host} AND PORT = #{port}
</select>
将源码中的mapper方法拷贝到自己的mapper中:
public interface WorkerNodeMapper extends BaseMapper<WorkerNode> {
/**
* Get {@link WorkerNode} by node host
*
* @param host
* @param port
* @return
*/
WorkerNode getWorkerNodeByHostPort(@Param("host") String host, @Param("port") String port);
/**
* Add {@link WorkerNode}
*
* @param workerNodeEntity
*/
void addWorkerNode(WorkerNode workerNodeEntity);
}
5. 自定义DisposableWorkerIdAssigner
将源码DisposableWorkerIdAssigner类加入到自己的项目中,并将其中的mapper方法修改成自己项目中的方法
6. 添加全局配置类,项目启动则可以增加机器节点
@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;
}
}
6. 在自己service实现中,直接引用UidGenerator方法生成id
@Service
public class WorkerNodeServiceImpl extends ServiceImpl<WorkerNodeMapper, WorkerNode> implements IWorkerNodeService {
@Resource
private UidGenerator uidGenerator;
@Override
public long genUid() {
return uidGenerator.getUID();
}
}
7. controller接口测试结果
/**
* 集成百度uid-generator生成id
* @return
*/
@GetMapping("/baidu/uid")
public long baiduUid(){
long uid = workerNodeService.genUid();
return uid;
}