看了GitHub上的两个生成唯一ID的算法程序(一个出自百度,一个出自美团),打算运行着试试看,至于原理什么的文档上讲得很详细了,此处不再一一粘贴了,此处只演示代码
https://github.com/baidu/uid-generator
https://github.com/zhuzhong/idleaf
百度UID生成器
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文件
<?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依赖
1 <dependency> 2 <groupId>org.apache.ignite</groupId> 3 <artifactId>ignite-zookeeper</artifactId> 4 <version>2.4.0</version> 5 </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-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
https://www.jianshu.com/p/c3913c5cc184
https://blog.csdn.net/z69183787/article/details/52403134
原文地址:https://www.cnblogs.com/a8457013/p/10075718.html