Springboot整合百度开源分布式ID生成器UIDGenerator

Springboot整合百度开源分布式ID生成器UIDGenerator

作者:FastCoder 2021-07-14 07:17:37

开发

前端

分布式 UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于docker等虚拟化环境下实例自动重启、漂移等场景。

[[411081]]

环境:sprinboot2.3.12.RELEASE + uid-generator1.0.0

简介

UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于docker等虚拟化环境下实例自动重启、漂移等场景。 在实现上, UidGenerator通过借用未来时间来解决sequence天然存在的并发限制; 采用RingBuffer来缓存已生成的UID, 并行化UID的生产和消费, 同时对CacheLine补齐,避免了由RingBuffer带来的硬件级「伪共享」问题. 最终单机QPS可达600万。

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

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进行自定义

CachedUidGenerator

RingBuffer环形数组,数组每个元素成为一个slot。RingBuffer容量,默认为Snowflake算法中sequence最大值,且为2^N。可通过boostPower配置进行扩容,以提高RingBuffer 读写吞吐量。

Tail指针、Cursor指针用于环形数组上读写slot:

  • Tail指针 表示Producer生产的最大序号(此序号从0开始,持续递增)。Tail不能超过Cursor,即生产者不能覆盖未消费的slot。当Tail已赶上curosr,此时可通过rejectedPutBufferHandler指定PutRejectPolicy
  • Cursor指针 表示Consumer消费到的最小序号(序号序列与Producer序列相同)。Cursor不能超过Tail,即不能消费未生产的slot。当Cursor已赶上tail,此时可通过rejectedTakeBufferHandler指定TakeRejectPolicy

 CachedUidGenerator采用了双RingBuffer,Uid-RingBuffer用于存储Uid、Flag-RingBuffer用于存储Uid状态(是否可填充、是否可消费)

由于数组元素在内存中是连续分配的,可最大程度利用CPU cache以提升性能。但同时会带来「伪共享」FalseSharing问题,为此在Tail、Cursor指针、Flag-RingBuffer中采用了CacheLine 补齐方式。

RingBuffer填充时机

  • 初始化预填充 RingBuffer初始化时,预先填充满整个RingBuffer.
  • 即时填充 Take消费时,即时检查剩余可用slot量(tail – cursor),如小于设定阈值,则补全空闲slots。阈值可通过paddingFactor来进行配置,请参考Quick Start中CachedUidGenerator配置
  • 周期填充 通过Schedule线程,定时补全空闲slots。可通过scheduleInterval配置,以应用定时填充功能,并指定Schedule时间间隔

以上为百度的官方介绍,接下来我们将其整合到Springboot项目中

UIDGenerator下载

在下面地址下载uid-generator

UIDGenerator环境配置

创建表

  1. DROP TABLE IF EXISTS WORKER_NODE; 
  2. CREATE TABLE WORKER_NODE 
  3.   ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id'
  4.   HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name'
  5.   PORT VARCHAR(64) NOT NULL COMMENT 'port'
  6.   TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER'
  7.   LAUNCH_DATE DATE NOT NULL COMMENT 'launch date'
  8.   MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time'
  9.   CREATED TIMESTAMP NOT NULL COMMENT 'created time'
  10.   PRIMARY KEY(ID) 
  11. )COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB; 

 将其项目中的mapper.xml文件copy到自己项目中,对应的WorkerNodeEntity,WorkerNodeDAO,

DisposableWorkerIdAssigner都copy到自己的项目中。

DisposableWorkerIdAssigner主要是修改注入的dao,因为这里我们需要修改默认的dao相关的配置。

项目配置

依赖

  1. <dependency> 
  2.   <groupId>mysql</groupId> 
  3.   <artifactId>mysql-connector-java</artifactId> 
  4.   <scope>runtime</scope> 
  5. </dependency> 
  6. <dependency> 
  7.   <groupId>org.mybatis.spring.boot</groupId> 
  8.   <artifactId>mybatis-spring-boot-starter</artifactId> 
  9.   <version>2.1.4</version> 
  10. </dependency> 
  11. <dependency> 
  12.   <groupId>com.github.pagehelper</groupId> 
  13.   <artifactId>pagehelper-spring-boot-starter</artifactId> 
  14.   <version>1.3.0</version> 
  15. </dependency> 

mybatis配置

  1. pagehelper: 
  2.   helperDialect: mysql 
  3.   reasonable: true 
  4.   pageSizeZero: true 
  5.   offsetAsPageNum: true 
  6.   rowBoundsWithCount: true 
  7. --- 
  8. mybatis: 
  9.   type-aliases-package: com.pack.domain 
  10.   mapper-locations: 
  11.   - classpath:/mappers/*.xml 
  12.   configuration: 
  13.     lazy-loading-enabled: false 
  14.     aggressive-lazy-loading: false  

 mapper文件中的namespace及对应domain修改为自己路径下的。

配置UIDGenerator

  1. @Configuration 
  2. public class UIDConfig { 
  3.      
  4.     @Bean 
  5.     public DefaultUidGenerator defaultUidGenerator(DisposableWorkerIdAssigner disposableWorkerIdAssigner) { 
  6.         DefaultUidGenerator defaultUidGenerator = new DefaultUidGenerator() ; 
  7.         defaultUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner) ; 
  8.         defaultUidGenerator.setTimeBits(29) ; 
  9.         defaultUidGenerator.setWorkerBits(21) ; 
  10.         defaultUidGenerator.setSeqBits(13) ; 
  11.         defaultUidGenerator.setEpochStr("2021-01-01") ; 
  12.         return defaultUidGenerator ; 
  13.     } 
  14.  

 注意这里的

DisposableWorkerIdAssigner是copy到自己项目中的,不是百度提供的。

  1. @Component 
  2. public class DisposableWorkerIdAssigner implements WorkerIdAssigner { 
  3.   @Resource 
  4.   private WorkerNodeMapper workerNodeDAO; 
  5.   // other code 

 到此所有的都配置完成了。

测试

  1. @Resource 
  2. private DefaultUidGenerator uidGenerator ; 
  3.      
  4. @Test 
  5. public void testGeneratorId() { 
  6.   for (int i = 0; i < 10; i++) { 
  7.     System.out.println(uidGenerator.getUID()) ; 
  8.   } 

完毕!!!

 

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/233823.html<

(0)
运维的头像运维
上一篇2025-04-20 19:35
下一篇 2025-04-20 19:36

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注