看了GitHub上的两个生成唯一ID的算法程序(一个出自百度,一个出自美团),打算运行着试试看,至于原理什么的文档上讲得很详细了,此处不再一一粘贴了,此处只演示代码
百度UID生成器
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 4.0.0
5
6 com.cjs.example
7 uid-generator-demo
8 0.0.1-SNAPSHOT
9 jar
10
11 uid-generator-demo
12
13
14
15 org.springframework.boot
16 spring-boot-starter-parent
17 2.0.3.RELEASE
18
19
20
21
22 UTF-8
23 UTF-8
24 1.8
25
26
27
28
29 org.mybatis.spring.boot
30 mybatis-spring-boot-starter
31 1.3.2
32
33
34 mysql
35 mysql-connector-java
36 5.1.46
37
38
39
40 org.apache.commons
41 commons-collections4
42 4.2
43
44
45 org.apache.commons
46 commons-lang3
47 3.7
48
49
50
51 org.springframework.boot
52 spring-boot-starter-test
53 test
54
55
56
57
58
59
60 org.springframework.boot
61 spring-boot-maven-plugin
62
63
64
65
66
SQL脚本
1DROP DATABASE IF EXISTS `mytest`;2CREATE DATABASE `mytest` ;3use `mytest`;4DROP TABLE IF EXISTS WORKER_NODE;5CREATE TABLE WORKER_NODE6(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',14PRIMARY KEY(ID)15 )COMMENT='DB WorkerID Assigner for UID Generator',ENGINE =INNODB;
复制代码
mapper文件
INSERT INTO WORKER_NODE
(HOST_NAME,
PORT,
TYPE,
LAUNCH_DATE,
MODIFIED,
CREATED)
VALUES (
#{hostName},
#{port},
#{type},
#{launchDate},
NOW(),
NOW())
SELECT
ID,
HOST_NAME,
PORT,
TYPE,
LAUNCH_DATE,
MODIFIED,
CREATED
FROM
WORKER_NODE
WHERE
HOST_NAME= #{host} AND PORT =#{port}
application.yml配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/mytest
username: root
password:123456driver-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
@SpringBootApplicationpublic classUidGeneratorDemoApplication {public static voidmain(String[] args) {
SpringApplication.run(UidGeneratorDemoApplication.class, args);
}
@AutowiredprivateWorkerIdAssigner workerIdAssigner;
@BeanpublicDefaultUidGenerator defaultUidGenerator() {
DefaultUidGenerator defaultUidGenerator= newDefaultUidGenerator();
defaultUidGenerator.setWorkerIdAssigner(workerIdAssigner);
defaultUidGenerator.setTimeBits(29);
defaultUidGenerator.setWorkerBits(21);
defaultUidGenerator.setSeqBits(13);
defaultUidGenerator.setEpochStr("2018-07-21");returndefaultUidGenerator;
}
@BeanpublicDisposableWorkerIdAssigner disposableWorkerIdAssigner() {return newDisposableWorkerIdAssigner();
}
@BeanpublicCachedUidGenerator cachedUidGenerator() {
CachedUidGenerator cachedUidGenerator= newCachedUidGenerator();
cachedUidGenerator.setWorkerIdAssigner(workerIdAssigner);
cachedUidGenerator.setTimeBits(29);
cachedUidGenerator.setWorkerBits(21);
cachedUidGenerator.setSeqBits(13);
cachedUidGenerator.setEpochStr("2018-07-21");returncachedUidGenerator;
}
}
测试
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)
@SpringBootTestpublic classUidGeneratorDemoApplicationTests {
@Autowired
@Qualifier("defaultUidGenerator")privateDefaultUidGenerator defaultUidGenerator;
@Autowired
@Qualifier("cachedUidGenerator")privateCachedUidGenerator cachedUidGenerator;26 27@Testpublic voidtestSerialGenerate() {long uid =defaultUidGenerator.getUID();
System.out.println(uid);
System.out.println(defaultUidGenerator.parseUID(uid));
}
@Testpublic voidtestSerialGenerate2() {long uid =cachedUidGenerator.getUID();
System.out.println(uid);
System.out.println(cachedUidGenerator.parseUID(uid));
}
}
美团UID生成器
Maven依赖
1
2 org.apache.ignite
3 ignite-zookeeper
4 2.4.0
5
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;
}
}
测试
@AutowiredprivateIdLeafService idLeafService;
@Testpublic voidtestSerialGenerate3() {
Long id=idLeafService.getId();
System.out.println(id);
}
个人感觉无论是从文档,原理,还是代码,觉得还是百度的那个比较好用(哇咔咔O(∩_∩)O哈哈~)
还有一个Redis的方案感觉也不错
完整代码上传至 https://github.com/chengjiansheng/uid-generator-demo.git
参考
最后,关于RingBuffer(循环缓冲区,或者叫 环形缓冲区)