Java生成全局唯一ID代码演示

看了GitHub上的两个生成唯一ID的算法程序(一个出自百度,一个出自美团),打算运行着试试看,至于原理什么的文档上讲得很详细了,此处不再一一粘贴了,此处只演示代码https://github.com/baidu/uid-generatorhttps://github.com/zhuzhong/idleaf

百度UID生成器

Maven依赖

 <?xml version="1.0" encoding="UTF-8"?>
 <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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>com.cjs.example</groupId>
     <artifactId>uid-generator-demo</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <name>uid-generator-demo</name>
     <description></description>
 
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.0.3.RELEASE</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <java.version>1.8</java.version>
     </properties>
 
     <dependencies>
         <dependency>
             <groupId>org.mybatis.spring.boot</groupId>
             <artifactId>mybatis-spring-boot-starter</artifactId>
             <version>1.3.2</version>
         </dependency>
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>5.1.46</version>
         </dependency>
 
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-collections4</artifactId>
             <version>4.2</version>
         </dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
             <version>3.7</version>
         </dependency>
 
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
 
     <build>
         <plugins>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
 
 </project>

SQL脚本

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

mapper文件

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.cjs.example.baidu.uid.worker.dao.WorkerNodeDAO">
     <resultMap id="workerNodeRes"
                type="com.cjs.example.baidu.uid.worker.entity.WorkerNodeEntity">
         <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.cjs.example.baidu.uid.worker.entity.WorkerNodeEntity">
         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>

application.yml配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mytest
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml

Spring Bean配置

 package com.cjs.example;
 
 import com.cjs.example.baidu.uid.impl.CachedUidGenerator;
 import com.cjs.example.baidu.uid.impl.DefaultUidGenerator;
 import com.cjs.example.baidu.uid.worker.DisposableWorkerIdAssigner;
 import com.cjs.example.baidu.uid.worker.WorkerIdAssigner;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.annotation.Bean;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 @EnableTransactionManagement
 @SpringBootApplication
 public class UidGeneratorDemoApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(UidGeneratorDemoApplication.class, args);
     }
 
     @Autowired
     private WorkerIdAssigner workerIdAssigner;
 
     @Bean
     public DefaultUidGenerator defaultUidGenerator() {
         DefaultUidGenerator defaultUidGenerator = new DefaultUidGenerator();
         defaultUidGenerator.setWorkerIdAssigner(workerIdAssigner);
         defaultUidGenerator.setTimeBits(29);
         defaultUidGenerator.setWorkerBits(21);
         defaultUidGenerator.setSeqBits(13);
         defaultUidGenerator.setEpochStr("2018-07-21");
         return defaultUidGenerator;
     }
 
     @Bean
     public DisposableWorkerIdAssigner disposableWorkerIdAssigner() {
         return new DisposableWorkerIdAssigner();
     }
 
     @Bean
     public CachedUidGenerator cachedUidGenerator() {
         CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
         cachedUidGenerator.setWorkerIdAssigner(workerIdAssigner);
         cachedUidGenerator.setTimeBits(29);
         cachedUidGenerator.setWorkerBits(21);
         cachedUidGenerator.setSeqBits(13);
         cachedUidGenerator.setEpochStr("2018-07-21");
         return cachedUidGenerator;
     }
 
 }

测试

 package com.cjs.example;
 
 import com.cjs.example.baidu.uid.impl.CachedUidGenerator;
 import com.cjs.example.baidu.uid.impl.DefaultUidGenerator;
 import com.cjs.example.meituan.idleaf.IdLeafService;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
 @SpringBootTest
 public class UidGeneratorDemoApplicationTests {
 
     @Autowired
     @Qualifier("defaultUidGenerator")
     private DefaultUidGenerator defaultUidGenerator;
 
     @Autowired
     @Qualifier("cachedUidGenerator")
     private CachedUidGenerator cachedUidGenerator;
 
 26     27 
     @Test
     public void testSerialGenerate() {
         long uid = defaultUidGenerator.getUID();
         System.out.println(uid);
         System.out.println(defaultUidGenerator.parseUID(uid));
     }
 
     @Test
     public void testSerialGenerate2() {
         long uid = cachedUidGenerator.getUID();
         System.out.println(uid);
         System.out.println(cachedUidGenerator.parseUID(uid));
     }
 
 }

图片描述

图片描述

美团UID生成器

Maven依赖

 <dependency>
     <groupId>org.apache.ignite</groupId>
     <artifactId>ignite-zookeeper</artifactId>
     <version>2.4.0</version>
 </dependency>

SQL脚本

 DROP TABLE IF EXISTS `id_segment`;
 
 CREATE TABLE `id_segment` (
   `biz_tag` varchar(50) DEFAULT NULL COMMENT '业务标识',
   `max_id` bigint(20) DEFAULT NULL COMMENT '分配的id号段的最大值',
   `p_step` bigint(20) DEFAULT NULL COMMENT '步长',
   `last_update_time` datetime DEFAULT NULL,
   `current_update_time` datetime DEFAULT NULL
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='号段存储表';
 
 insert  into `id_segment`(`biz_tag`,`max_id`,`p_step`,`last_update_time`,`current_update_time`) values ('Order',60,20,'2018-07-21 15:44:02','2018-07-21 16:25:07');

Spring Bean配置

 package com.cjs.example;
 
 import com.cjs.example.meituan.idleaf.IdLeafService;
 import com.cjs.example.meituan.idleaf.support.MysqlIdLeafServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.annotation.Bean;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 @EnableTransactionManagement
 @SpringBootApplication
 public class UidGeneratorDemoApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(UidGeneratorDemoApplication.class, args);
     }
 
     @Autowired
     private JdbcTemplate jdbcTemplate;
 
     @Bean(initMethod = "init")
     public IdLeafService idLeafService() {
         MysqlIdLeafServiceImpl mysqlIdLeafService = new MysqlIdLeafServiceImpl();
         mysqlIdLeafService.setJdbcTemplate(jdbcTemplate);
         mysqlIdLeafService.setAsynLoadingSegment(true);
         mysqlIdLeafService.setBizTag("Order");
         return mysqlIdLeafService;
     }
 }

测试

 @Autowired
 private IdLeafService idLeafService;
 
 @Test
 public void testSerialGenerate3() {
     Long id = idLeafService.getId();
     System.out.println(id);
 }

图片描述

图片描述

个人感觉无论是从文档,原理,还是代码,觉得还是百度的那个比较好用(哇咔咔O(∩_∩)O哈哈~)还有一个Redis的方案感觉也不错完整代码上传至 https://github.com/chengjiansheng/uid-generator-demo.git

参考

https://github.com/baidu/uid-generatorhttps://tech.meituan.com/MT_Leaf.html?utm_source=tuicool&utm_medium=referralhttps://github.com/zhuzhong/idleaf

https://blog.csdn.net/liubenlong007/article/details/53884447https://www.cnblogs.com/baiwa/p/5318432.htmlhttps://blog.csdn.net/imi00/article/details/78629710

最后,关于RingBuffer(循环缓冲区,或者叫 环形缓冲区)https://blog.csdn.net/u011046042/article/details/51853535https://www.jianshu.com/p/c3913c5cc184https://blog.csdn.net/z69183787/article/details/52403134