当前位置: 首页 > 工具软件 > UidGenerator > 使用案例 >

spring集成百度UidGenerator

沈长恨
2023-12-01

前言

雪花算法对时间倒退问题
官方文档

注意事项:
依赖版本:Java8及以上版本, MySQL(内置WorkerID分配器, 启动阶段通过DB进行分配; 如自定义实现, 则DB非必选依赖)。

这里参考大佬的帖子,链接放最后了。

百度UidGenerator是一个分布式数据库id生成器,本文在SpringBoot项目快速优雅集成百度UidGenerator,使用的是 uid-generator-spring-boot-starter ,它是基于百度UidGenerator,在此基础上做了部分改进。

  • 改造为spring-boot-starter的形式,不用部署为分布式,直接建表、在项目中引入,即可使用
  • 针对时钟回拨,提供了修正选项(默认启用,可通过配置关闭),小于阈值直接休眠,大于阈值更改机器号
  • 对机器id用尽提供了复用策略:取余
  • 解除id位数限制,由“必须64位”改为“不大于64位”,可根据需要获取更短id

集成步骤

pom文件

这里跟项目冲突,需要排除下jar自带的mybatis

<dependency>
            <groupId>com.github.wujun234</groupId>
            <artifactId>uid-generator-spring-boot-starter</artifactId>
            <version>1.0.3.RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>mybatis-spring</artifactId>
                    <groupId>org.mybatis</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>mybatis</artifactId>
                    <groupId>org.mybatis</groupId>
                </exclusion>
            </exclusions>
        </dependency>

id生成实现类

提供了两种生成器: DefaultUidGenerator、CachedUidGenerator。如对UID生成性能有要求, 请使用CachedUidGenerator

@Component
public class IdGen {

    @Autowired
    private CachedUidGenerator cachedUidGenerator;

    /**
     * 获取uid
     *
     * @return
     */
    public long getUID() {
        return cachedUidGenerator.getUID();
    }

    /**
     * 格式化传入的uid,方便查看其实际含义
     *
     * @param uid
     * @return
     */
    public String parseUID(long uid) {
        return cachedUidGenerator.parseUID(uid);
    }
}

yml配置

关于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年.

uid:
  # 该时间最好写最新时间s
  epochStr: 2022-01-01
  # 时间位, 默认:30
  timeBits: 41
  # 机器位, 默认:16
  workerBits: 10
  # 序列号, 默认:7
  seqBits: 12
  # 是否容忍时钟回拨, 默认:true
  enableBackward: true
  # RingBuffer size扩容参数, 可提高UID生成的吞吐量, 默认:3
  CachedUidGenerator:
    boostPower: 3
    # 指定何时向RingBuffer中填充UID, 取值为百分比(0, 100), 默认为50
    paddingFactor: 50

创建表

DROP DATABASE IF EXISTS `xxxx`;
CREATE DATABASE `xxxx` ;
use `xxxx`;
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;

测试

运行单测CachedUidGeneratorTest, 展示UID生成、解析等功能

@Resource
private IdGenerator idGenerator;

@Test
public void testSerialGenerate() {
    // Generate UID
    long uid = idGenerator.getUID();

    // Parse UID into [Timestamp, WorkerId, Sequence]
    // {"UID":"180363646902239241","parsed":{    "timestamp":"2017-01-19 12:15:46",    "workerId":"4",    "sequence":"9"        }}
    System.out.println(idGenerator.parseUID(uid));

}

https://blog.csdn.net/MonsterFaker/article/details/120847264

 类似资料: