分布式ID生成方案(六):SpringBoot2.X集成百度UidGenerator

简介

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;
 }

完整代码地址:SpringBoot2.X+MybatisPlus+UidGenerator

猜你喜欢

转载自blog.csdn.net/u013034223/article/details/105706516