看了GitHub上的两个生成唯一ID的算法程序(一个出自百度,一个出自美团),打算运行着试试看,至于原理什么的文档上讲得很详细了,此处不再一一粘贴了,此处只演示代码
https://github.com/baidu/uid-generator
https://github.com/zhuzhong/idleaf
百度UID生成器
Maven依赖
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 6 <groupId>com.cjs.example</groupId> 7 <artifactId>uid-generator-demo</artifactId> 8 <version>0.0.1-SNAPSHOT</version> 9 <packaging>jar</packaging> 10 11 <name>uid-generator-demo</name> 12 <description></description> 13 14 <parent> 15 <groupId>org.springframework.boot</groupId> 16 <artifactId>spring-boot-starter-parent</artifactId> 17 <version>2.0.3.RELEASE</version> 18 <relativePath/> <!-- lookup parent from repository --> 19 </parent> 20 21 <properties> 22 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 23 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 24 <java.version>1.8</java.version> 25 </properties> 26 27 <dependencies> 28 <dependency> 29 <groupId>org.mybatis.spring.boot</groupId> 30 <artifactId>mybatis-spring-boot-starter</artifactId> 31 <version>1.3.2</version> 32 </dependency> 33 <dependency> 34 <groupId>mysql</groupId> 35 <artifactId>mysql-connector-java</artifactId> 36 <version>5.1.46</version> 37 </dependency> 38 39 <dependency> 40 <groupId>org.apache.commons</groupId> 41 <artifactId>commons-collections4</artifactId> 42 <version>4.2</version> 43 </dependency> 44 <dependency> 45 <groupId>org.apache.commons</groupId> 46 <artifactId>commons-lang3</artifactId> 47 <version>3.7</version> 48 </dependency> 49 50 <dependency> 51 <groupId>org.springframework.boot</groupId> 52 <artifactId>spring-boot-starter-test</artifactId> 53 <scope>test</scope> 54 </dependency> 55 </dependencies> 56 57 <build> 58 <plugins> 59 <plugin> 60 <groupId>org.springframework.boot</groupId> 61 <artifactId>spring-boot-maven-plugin</artifactId> 62 </plugin> 63 </plugins> 64 </build> 65 66 </project>
SQL脚本
1 DROP DATABASE IF EXISTS `mytest`; 2 CREATE DATABASE `mytest` ; 3 use `mytest`; 4 DROP TABLE IF EXISTS WORKER_NODE; 5 CREATE TABLE WORKER_NODE 6 ( 7 ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id', 8 HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name', 9 PORT VARCHAR(64) NOT NULL COMMENT 'port', 10 TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER', 11 LAUNCH_DATE DATE NOT NULL COMMENT 'launch date', 12 MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time', 13 CREATED TIMESTAMP NOT NULL COMMENT 'created time', 14 PRIMARY KEY(ID) 15 )COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB;
mapper文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.cjs.example.baidu.uid.worker.dao.WorkerNodeDAO"> 4 <resultMap id="workerNodeRes" 5 type="com.cjs.example.baidu.uid.worker.entity.WorkerNodeEntity"> 6 <id column="ID" jdbcType="BIGINT" property="id" /> 7 <result column="HOST_NAME" jdbcType="VARCHAR" property="hostName" /> 8 <result column="PORT" jdbcType="VARCHAR" property="port" /> 9 <result column="TYPE" jdbcType="INTEGER" property="type" /> 10 <result column="LAUNCH_DATE" jdbcType="DATE" property="launchDate" /> 11 <result column="MODIFIED" jdbcType="TIMESTAMP" property="modified" /> 12 <result column="CREATED" jdbcType="TIMESTAMP" property="created" /> 13 </resultMap> 14 15 <insert id="addWorkerNode" useGeneratedKeys="true" keyProperty="id" 16 parameterType="com.cjs.example.baidu.uid.worker.entity.WorkerNodeEntity"> 17 INSERT INTO WORKER_NODE 18 (HOST_NAME, 19 PORT, 20 TYPE, 21 LAUNCH_DATE, 22 MODIFIED, 23 CREATED) 24 VALUES ( 25 #{hostName}, 26 #{port}, 27 #{type}, 28 #{launchDate}, 29 NOW(), 30 NOW()) 31 </insert> 32 33 <select id="getWorkerNodeByHostPort" resultMap="workerNodeRes"> 34 SELECT 35 ID, 36 HOST_NAME, 37 PORT, 38 TYPE, 39 LAUNCH_DATE, 40 MODIFIED, 41 CREATED 42 FROM 43 WORKER_NODE 44 WHERE 45 HOST_NAME = #{host} AND PORT = #{port} 46 </select> 47 </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配置
1 package com.cjs.example; 2 3 import com.cjs.example.baidu.uid.impl.CachedUidGenerator; 4 import com.cjs.example.baidu.uid.impl.DefaultUidGenerator; 5 import com.cjs.example.baidu.uid.worker.DisposableWorkerIdAssigner; 6 import com.cjs.example.baidu.uid.worker.WorkerIdAssigner; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.boot.SpringApplication; 9 import org.springframework.boot.autoconfigure.SpringBootApplication; 10 import org.springframework.context.annotation.Bean; 11 import org.springframework.jdbc.core.JdbcTemplate; 12 import org.springframework.transaction.annotation.EnableTransactionManagement; 13 14 @EnableTransactionManagement 15 @SpringBootApplication 16 public class UidGeneratorDemoApplication { 17 18 public static void main(String[] args) { 19 SpringApplication.run(UidGeneratorDemoApplication.class, args); 20 } 21 22 @Autowired 23 private WorkerIdAssigner workerIdAssigner; 24 25 @Bean 26 public DefaultUidGenerator defaultUidGenerator() { 27 DefaultUidGenerator defaultUidGenerator = new DefaultUidGenerator(); 28 defaultUidGenerator.setWorkerIdAssigner(workerIdAssigner); 29 defaultUidGenerator.setTimeBits(29); 30 defaultUidGenerator.setWorkerBits(21); 31 defaultUidGenerator.setSeqBits(13); 32 defaultUidGenerator.setEpochStr("2018-07-21"); 33 return defaultUidGenerator; 34 } 35 36 @Bean 37 public DisposableWorkerIdAssigner disposableWorkerIdAssigner() { 38 return new DisposableWorkerIdAssigner(); 39 } 40 41 @Bean 42 public CachedUidGenerator cachedUidGenerator() { 43 CachedUidGenerator cachedUidGenerator = new CachedUidGenerator(); 44 cachedUidGenerator.setWorkerIdAssigner(workerIdAssigner); 45 cachedUidGenerator.setTimeBits(29); 46 cachedUidGenerator.setWorkerBits(21); 47 cachedUidGenerator.setSeqBits(13); 48 cachedUidGenerator.setEpochStr("2018-07-21"); 49 return cachedUidGenerator; 50 } 51 52 }
测试
1 package com.cjs.example; 2 3 import com.cjs.example.baidu.uid.impl.CachedUidGenerator; 4 import com.cjs.example.baidu.uid.impl.DefaultUidGenerator; 5 import com.cjs.example.meituan.idleaf.IdLeafService; 6 import org.junit.Test; 7 import org.junit.runner.RunWith; 8 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.beans.factory.annotation.Qualifier; 10 import org.springframework.boot.test.context.SpringBootTest; 11 import org.springframework.test.context.junit4.SpringRunner; 12 13 @RunWith(SpringRunner.class) 14 @SpringBootTest 15 public class UidGeneratorDemoApplicationTests { 16 17 @Autowired 18 @Qualifier("defaultUidGenerator") 19 private DefaultUidGenerator defaultUidGenerator; 20 21 @Autowired 22 @Qualifier("cachedUidGenerator") 23 private CachedUidGenerator cachedUidGenerator; 24 25 26 27 28 @Test 29 public void testSerialGenerate() { 30 long uid = defaultUidGenerator.getUID(); 31 System.out.println(uid); 32 System.out.println(defaultUidGenerator.parseUID(uid)); 33 } 34 35 @Test 36 public void testSerialGenerate2() { 37 long uid = cachedUidGenerator.getUID(); 38 System.out.println(uid); 39 System.out.println(cachedUidGenerator.parseUID(uid)); 40 } 41 42 }
美团UID生成器
Maven依赖
1 <dependency> 2 <groupId>org.apache.ignite</groupId> 3 <artifactId>ignite-zookeeper</artifactId> 4 <version>2.4.0</version> 5 </dependency>
SQL脚本
1 DROP TABLE IF EXISTS `id_segment`; 2 3 CREATE TABLE `id_segment` ( 4 `biz_tag` varchar(50) DEFAULT NULL COMMENT '业务标识', 5 `max_id` bigint(20) DEFAULT NULL COMMENT '分配的id号段的最大值', 6 `p_step` bigint(20) DEFAULT NULL COMMENT '步长', 7 `last_update_time` datetime DEFAULT NULL, 8 `current_update_time` datetime DEFAULT NULL 9 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='号段存储表'; 10 11 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配置
1 package com.cjs.example; 2 3 import com.cjs.example.meituan.idleaf.IdLeafService; 4 import com.cjs.example.meituan.idleaf.support.MysqlIdLeafServiceImpl; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.boot.SpringApplication; 7 import org.springframework.boot.autoconfigure.SpringBootApplication; 8 import org.springframework.context.annotation.Bean; 9 import org.springframework.jdbc.core.JdbcTemplate; 10 import org.springframework.transaction.annotation.EnableTransactionManagement; 11 12 @EnableTransactionManagement 13 @SpringBootApplication 14 public class UidGeneratorDemoApplication { 15 16 public static void main(String[] args) { 17 SpringApplication.run(UidGeneratorDemoApplication.class, args); 18 } 19 20 @Autowired 21 private JdbcTemplate jdbcTemplate; 22 23 @Bean(initMethod = "init") 24 public IdLeafService idLeafService() { 25 MysqlIdLeafServiceImpl mysqlIdLeafService = new MysqlIdLeafServiceImpl(); 26 mysqlIdLeafService.setJdbcTemplate(jdbcTemplate); 27 mysqlIdLeafService.setAsynLoadingSegment(true); 28 mysqlIdLeafService.setBizTag("Order"); 29 return mysqlIdLeafService; 30 } 31 }
测试
1 @Autowired 2 private IdLeafService idLeafService; 3 4 @Test 5 public void testSerialGenerate3() { 6 Long id = idLeafService.getId(); 7 System.out.println(id); 8 }
个人感觉无论是从文档,原理,还是代码,觉得还是百度的那个比较好用(哇咔咔O(∩_∩)O哈哈~)
还有一个Redis的方案感觉也不错
完整代码上传至 https://github.com/chengjiansheng/uid-generator-demo.git
参考
https://github.com/baidu/uid-generator
https://tech.meituan.com/MT_Leaf.html?utm_source=tuicool&utm_medium=referral
https://github.com/zhuzhong/idleaf
https://blog.csdn.net/liubenlong007/article/details/53884447
https://www.cnblogs.com/baiwa/p/5318432.html
https://blog.csdn.net/imi00/article/details/78629710
最后,关于RingBuffer(循环缓冲区,或者叫 环形缓冲区)
https://blog.csdn.net/u011046042/article/details/51853535