2
2
uid-generator-spring-boot
3
3
==========================
4
4
5
- UidGenerator是Java实现的, 基于[ Snowflake] ( https://github.com/twitter/snowflake ) 算法的唯一ID生成器 。
5
+ UidGenerator是Java实现的, 基于[ Snowflake] ( https://github.com/twitter/snowflake ) 算法的分布式唯一ID生成器 。
6
6
7
7
基与 [ Snowflake] ( https://github.com/twitter/snowflake ) ,[ 百度UidGenerator] ( https://github.com/baidu/uid-generator ) ,[ uid-generator-spring-boot-starter] ( https://github.com/wujun234/uid-generator-spring-boot-starter )
8
8
9
9
10
10
* 更改了打包结构,抽出了Worker node id的生成接口, 使其可以自定义实现分配 Worker node id的方法, 本项目中实现了两种数据库存储的方法:
11
11
* 支持 Spring boot Autoconfigure
12
- * 支持 jdbc 和 r2dbc 两种数据库连接方式
13
-
14
- * mybatis jdbc 实现 [ uid-worker-id-jdbc-spring-boot-starter ] ( https://github.com/cooperlyt/uid-generator-spring-boot/tree/master/uid-worker-id-jdbc-spring-boot-starter )
15
- * mybatis r2dbc 实现 [ uid-worker-id- r2dbc-spring-boot-start ] ( https://github.com/cooperlyt/uid-generator-spring-boot/tree/master/uid-worker-id-r2dbc-spring-boot-starter )
12
+ * 支持响应式编程,返回 ` Mono<Long> ` ,
13
+ * 在CachedUidGenerator:消耗速度高于填充速度时,等待填充完成后以非阻塞的方式通知订阅者。
14
+ * 在DefaultUidGenerator不允许使用未来时间(未到达的时间)状态:当前时间ID耗尽等待下一秒后非阻塞的方式通知订阅者
15
+ * 支持 mybatis jdbc, mybatis r2bc , jap jdbc ,jap r2dbc 四种数据库连接方式
16
16
17
17
你以可以根据[ 接口包] ( https://github.com/cooperlyt/uid-generator-spring-boot/tree/master/uid-generator-api ) 自己实现Worker node分配的实现
18
18
@@ -26,45 +26,56 @@ UidGenerator是Java实现的, 基于[Snowflake](https://github.com/twitter/snowf
26
26
27
27
#### spring boot autoconfig 方式
28
28
``` xml
29
- <dependency >
30
- <groupId >uid-generator-spring-boot-starter</groupId >
31
- <artifactId >uid</artifactId >
32
- <version >1.0.3.RELEASE</version >
33
- </dependency >
34
29
35
- <!-- 选择一种 worker node 分配方式 -->
30
+ <!-- 根据你的项目环境 选择一种 worker node 分配方式 -->
36
31
37
- <!-- jdbc -->
32
+ <!-- 以下仅选一种即可,多了会冲突 -->
38
33
34
+ <!-- mybatis jdbc -->
39
35
<dependency >
40
36
<groupId >cooperlyt.github.io</groupId >
41
- <artifactId >uid-worker-id -jdbc-spring-boot-starter</artifactId >
42
- <version >1.0.1.BATE </version >
37
+ <artifactId >uid-generator-mybatis -jdbc-spring-boot-starter</artifactId >
38
+ <version >${uid.version} </version >
43
39
</dependency >
44
40
45
- <!-- 选择你的数据库jdbc驱动 -->
41
+ <!-- mybatis r2dbc -->
46
42
<dependency >
47
- <groupId >org.mariadb.jdbc</groupId >
48
- <artifactId >mariadb-java-client</artifactId >
43
+ <groupId >cooperlyt.github.io</groupId >
44
+ <artifactId >uid-generator-mybatis-r2dbc-spring-boot-starter</artifactId >
45
+ <version >${uid.version}</version >
49
46
</dependency >
50
47
51
- <!-- r2dbc -->
52
48
49
+ <!-- jpa jdbc -->
50
+ <dependency >
51
+ <groupId >cooperlyt.github.io</groupId >
52
+ <artifactId >uid-generator-jap-jdbc-spring-boot-starter</artifactId >
53
+ <version >${uid.version}</version >
54
+ </dependency >
55
+
56
+ <!-- jpa r2dbc -->
53
57
<dependency >
54
- <groupId >io .github.cooperlyt </groupId >
55
- <artifactId >uid-worker-id -r2dbc-spring-boot-starter</artifactId >
56
- <version >1.0.1.BATE </version >
58
+ <groupId >cooperlyt .github.io </groupId >
59
+ <artifactId >uid-generator-jpa -r2dbc-spring-boot-starter</artifactId >
60
+ <version >${uid.version} </version >
57
61
</dependency >
58
62
59
- <!-- 选择你的数据库据r2dbc驱动 -->
63
+ <!-- 选择相印的数据库驱动包 -->
64
+ <!-- jdbc驱动 -->
65
+ <dependency >
66
+ <groupId >org.mariadb.jdbc</groupId >
67
+ <artifactId >mariadb-java-client</artifactId >
68
+ </dependency >
69
+
70
+ <!-- r2dbc驱动 -->
60
71
<dependency >
61
72
<groupId >org.mariadb</groupId >
62
73
<artifactId >r2dbc-mariadb</artifactId >
63
74
<version >1.1.3</version >
64
75
</dependency >
65
76
66
77
```
67
-
78
+ 由于开发时Mybatis官方还不支持r2dbc所以使用了 [ reactive-mybatis-support ] ( https://github.com/chenggangpro/reactive-mybatis-support )
68
79
69
80
70
81
### 数据库(可选)
@@ -86,22 +97,7 @@ PRIMARY KEY(ID)
86
97
87
98
### spring boot 配置
88
99
89
- #### ID 生成 配置
90
- ``` yml
91
- uid :
92
- timeBits : 30 # 时间位, 默认:30
93
- workerBits : 16 # 机器位, 默认:16
94
- seqBits : 7 # 序列号, 默认:7
95
- epochStr : " 2019-02-20" # 初始时间, 默认:"2019-02-20"
96
- enableBackward : true # 是否容忍时钟回拨, 默认:true
97
- maxBackwardSeconds : 1 # 时钟回拨最长容忍时间(秒), 默认:1
98
- CachedUidGenerator : # CachedUidGenerator相关参数
99
- boostPower : 3 # RingBuffer size扩容参数, 可提高UID生成的吞吐量, 默认:3
100
- paddingFactor : 50 # 指定何时向RingBuffer中填充UID, 取值为百分比(0, 100), 默认为50
101
- # scheduleInterval: 60 # 默认:不配置此项, 即不使用Schedule线程. 如需使用, 请指定Schedule线程时间间隔, 单位:秒
102
- ```
103
-
104
- #### jdbc 配置
100
+ #### jdbc 配置 (以mariadb为例)
105
101
106
102
``` yml
107
103
mybatis :
@@ -128,7 +124,7 @@ r2dbc:
128
124
spring :
129
125
r2dbc :
130
126
mybatis :
131
- r2dbc-url : r2dbc:mysql ://127.0.0.1:3306/database
127
+ r2dbc-url : r2dbc:mariadb ://127.0.0.1:3306/database
132
128
username : root
133
129
password : ****
134
130
pool :
@@ -142,30 +138,47 @@ spring:
142
138
143
139
```
144
140
145
- #### 自定义 拒绝策略
141
+ #### 自定义 CachedUidGenerator 拒绝策略
146
142
147
143
``` java
144
+ // 生成一批ID后由于buffer环已满无法填充时的处理方式, 默认为丢弃并打印日志
148
145
@Bean
149
146
RejectedPutBufferHandler customPutHandler() {
150
- return (r, i ) - > {
147
+ return (buffer, id ) - > {
151
148
do your
152
149
};
153
150
}
154
151
152
+ // 由于消耗过快使用到了未来时间(未到达的时间), 默认为允许并打印日志
155
153
@Bean
156
- RejectedTakeBufferHandler customTakeHandler () {
157
- return (r, i ) - > {
154
+ TimeIsFutureHandler customFutureTimeHandler () {
155
+ return (futureTime, currentTime ) - > {
158
156
do your
159
157
};
160
158
}
161
159
162
160
```
163
161
162
+ #### ID 生成配置, 如应用在生产环境请确认以下参数,并确保你已经理解每个参数的意义。
163
+ ``` yml
164
+ uid :
165
+ timeBits : 30 # 时间位, 默认:30
166
+ workerBits : 16 # 机器位, 默认:16
167
+ seqBits : 7 # 序列号, 默认:7
168
+ epochStr : " 2023-02-17" # 初始时间, 默认:"2019-02-20"
169
+ enableFutureTime : false # 允许使用未来时间生成ID,可以使用多少未来时间由 maxBackwardSeconds 控制, 默认: false
170
+ maxBackwardSeconds : 1 # 系统时钟回拨和使用未来时间最长容忍时间(秒), 默认:1
171
+ CachedUidGenerator : # CachedUidGenerator相关参数
172
+ boostPower : 3 # RingBuffer size扩容参数, 可提高UID生成的吞吐量, 默认:3
173
+ paddingFactor : 50 # 指定何时向RingBuffer中填充UID, 取值为百分比(0, 100), 默认为50
174
+ # scheduleInterval: 60 # 默认:不配置此项, 即不使用Schedule线程定时填充buffer环. 如需使用, 请指定Schedule线程时间间隔, 单位:秒
175
+ ```
176
+
164
177
### 使用
165
178
179
+ ####
166
180
167
181
``` java
168
-
169
182
// 实时生成
170
183
// @Resource
171
184
// private UidGenerator defaultUidGenerator;
@@ -174,15 +187,33 @@ spring:
174
187
@Resource
175
188
private UidGenerator cachedUidGenerator;
176
189
190
+
191
+
177
192
@Test
178
193
public void testSerialGenerate() {
179
194
// Generate UID
180
- long uid = cachedUidGenerator. getUID();
195
+ Mono< Long > uid = cachedUidGenerator. getUID();
181
196
182
197
// Parse UID into [Timestamp, WorkerId, Sequence]
183
198
// {"UID":"450795408770","timestamp":"2019-02-20 14:55:39","workerId":"27","sequence":"2"}
184
199
System . out. println(cachedUidGenerator. parseUID(uid));
185
200
186
201
}
187
202
```
188
- ** defaultUidGenerator** 和 ** cachedUidGenerator** 的区别和选择方式请参见 [ 百度UidGenerator] ( https://github.com/baidu/uid-generator )
203
+
204
+ #### 策略选择
205
+
206
+
207
+ * CachedUidGenerator:
208
+
209
+ 适合** 持续高消耗量** 的ID分发,此方式会一定程度上的增加内存和CPU缓存占用。
210
+
211
+ * enableFutureTime 为true时的 DefaultUidGenerator:
212
+
213
+ 适合** 偶然突发的消费增加后持续保持低消耗量** 的ID分发,此方式在突发高消费时的性能要比CachedUidGenerator还要高,但不应该持续保持高消耗(可消耗的未来时间由maxBackwardSeconds控制,超出后抛出异常),因为过度使用未来时间有可能会造成服务重启后生成重复ID。
214
+
215
+ * enableFutureTime 为false时的 DefaultUidGenerator:
216
+
217
+ 适合** 低消耗量实时** 的ID分发,此方式一但消耗量高于当前时间的发号量时会返回一个等待响应,等待下一可用时间后发出ID,最大等待时间由maxBackwardSeconds控制,超出后抛出异常。
218
+
219
+ 对于发号性能的测式可使用此 [ 测试用例] ( https://github.com/cooperlyt/uid-generator-spring-boot/tree/master/uid-generator-spring-boot-starter/src/test/java/io/github/cooperlyt/cloud/uid ) 进行测试,并参见[ 百度UidGenerator] ( https://github.com/baidu/uid-generator )
0 commit comments