SpringBoot集成uidGenerator

  1. 下载源码 https://github.com/baidu/uid-generator

  2. 新建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>
  1. 将源码的整个src目录拷贝到项目下,注意common-lang包我换成了common-lang3,所以有些地方需要改一下。
  2. install项目到本地仓库
  3. 打开另一个maven项目,测试是否可用,引入依赖:
        <dependency>
            <groupId>com.deliciousgroupId>
            <artifactId>uid-generatorartifactId>
            <version>1.0.0-SNAPSHOTversion>
        dependency>
  1. 数据库建表
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;
  1. mapper

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> {
}
  1. 编写WorkerNodeDaoImpl,注意这个类是实现com.baidu.fsg.uid.worker.dao.WorkerNodeDAO接口的,
    基于MybatisPlus。
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);
    }
}
  1. DisposableWorkerIdAssigner
/**
 * 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; } }

  1. CachedUidGeneratorConfig
@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_第1张图片
总结
使用springboot整合了uidGenerator,使用mybatisplus代替了mybatis。

你可能感兴趣的:(spring,boot,java)