分布式ID生成器-GeDid
源起
尝试设计实现一个分布式id工具,已是好几年前的事了,这里是历史的痕迹。
最初实现了基于redis(jedis客户端)的版本,而后在19年左右,考虑接入Zookeeper版本的。但是一直没有着手去做。
最近借助一次"翻新"的机会,把它又拿出来,考虑完成Zookeeper版本的实现。因spring-boot-x已经有了很多的基础,也便于Gedid
在springboot环境下使用,与springboot的整合和利用已有的springboot资源,所以考虑把Gedid
迁移至spring-boot-x,以至于进行了大量的改造。多次调整之后,变有了现在的结果。也有了这个文章的整理。
这个文章目的:把Gedid
的使用场景和使用方式道明白。
开始
引入依赖
|
|
在启动类上加入
@EnableExtension
目前最新版本
ID引擎
目前支持引擎如下:
-
EtcdIdEngine
since v4.3.0 [ 2021.7.3更新 ]- 基于
PutResponse
的Prev_Kv
的version
; - 对应的id类型是
Long
; - 支持业务隔离,对应的
businessName
就是业务的标识; - 使用
jetcd
客户端; etcd
存储的数据key格式为:"gedid-{businessName}
",可以通过此查询对应的数据; since v4.3.1
- 基于
-
SnowflakeIdEngine
since v4.3.0 [ 2021.7.3更新 ]- 对应的id类型是
Long
; - 天然支持业务隔离;
- 对应的id类型是
-
RedisIdEngine
- 基于redis的
incr
指令; - 对应的id类型是
Long
; - 支持业务隔离,对应的
businessName
就是业务的标识; - 支持
lettuce
和jedis
,默认为lettuce
; redis
存储的数据key格式为:"gedid:{businessName}
",可以通过此查询对应的数据; since v4.3.1
- 基于redis的
-
ZookeeperIdEngine
-
基于
CreateMode.PERSISTENT
节点的version
(ZookeeperIdEngineMode#DATA_VERSION
)或zxmid
(ZookeeperIdEngineMode#DATA_ZX_MID
);可以注入不同的Bean配置使用的mode,如下:1 2 3 4
@Bean public ZookeeperIdEngineMode zookeeperIdEngineMode() { return ZookeeperIdEngineMode.DATA_ZX_MID; }
-
对应的Id类型是
Long
; -
支持业务隔离,对应的
businessName
就是业务的标识; -
使用
curator
客户端;使用
ZookeeperIdEngineMode#DATA_VERSION
时,对应id受限于integer类型的version
的取值范围。使用
ZookeeperIdEngineMode#DATA_ZX_MID
时,对应id可能会因为zk的重启出现较大范围的跳跃。 -
Zookeeper
存储的path数据格式为:"/gedid-{businessName}
",可以通过此查询对应的数据; since v4.3.1
-
-
UuidEngine
- 基于
java.util.UUID#randomUUID
; - 对应id类型为
String
; - 天然支持业务隔离;
- 基于
使用
配置说明
-
EtcdIdEngine
[ 2021.7.3更新 ]1 2 3 4 5 6 7
openingo: gedid: engine: etcd: endpoints: http://localhost:2379 user: user password: password
多个endpoint用英文
,
分割 -
SnowflakeIdEngine
[ 2021.7.3更新 ]无需配置;默认
workerId
及dataCenterId
都是0L
,可以通过重新注入SnowflakeIdEngine
到SpringIoC的方式调整二者,二者取值均需<=31L
。1 2 3 4 5 6 7 8 9
@Configuration static class SnowflakeConfig { @Bean @ConditionalOnMissingBean SnowflakeIdEngine snowflakeIdEngine() { return new SnowflakeIdEngine(12L, 13L); } }
-
RedisIdEngine
与
spring-boot-starter-data-redis
配置类似,配置前缀为openingo.gedid.engine.redis
。 -
ZookeeperIdEngine
与
spring-cloud-starter-zookeeper-discovery
的配置类似,配置前缀为openingo.gedid.engine.zookeeper
。 -
UuidEngine
无需配置
-
配置示例
1 2 3 4 5 6 7 8 9 10 11 12
openingo: gedid: engine: zookeeper: connect-string: localhost:2182 redis: cluster: nodes: localhost:7291,localhost:7292,localhost:7293,localhost:7294,localhost:7295,localhost:7296 etcd: endpoints: http://localhost:2379 user: user password: password
示例中使用了2182端口对应的zk,与默认的2181区分,目的是为了说明与默认配置的隔离;redis使用的集群配置。
redis和Zookeeper的配置前缀与默认的配置完全隔离,目的是将业务使用的redis和Zookeeper和GeDid使用的redis、Zookeeper隔离开,如此配置不会造成业务与GeDid是相互影响。当然也可以配置成完全一样的服务器信息。
业务配置
-
根据业务情况,参考如下配置
DidLoader
【推荐】1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/** * IdLoaderConfig * * @author Qicz * @since 2021/6/24 16:03 */ @Configuration public class IdLoaderConfig implements DidLoaderConfigurer { @Bean public ZookeeperIdEngineMode zookeeperIdEngineMode() { return ZookeeperIdEngineMode.DATA_ZX_MID; } @Override public void configureDidLoader(DidLoader didLoader) { // business abc didLoader.follow("redis://abc"); // business a didLoader.follow("redis", "a"); // business b didLoader.follow("redis", "b"); // business zk didLoader.follow("zookeeper", "zk"); // business uuid didLoader.follow("uuid", "uuid"); } }
-
业务中使用
1 2 3 4 5 6
@Autowired DidLoader didLoader; didLoader.next(businessName); // 下一个Id didLoad.nextToLong(businessName); // 下一个Long Id didLoad.nextToString(businessName); //下一个String Id
-
动态配置
DidLoader
某些特定的情况,可能需要动态的配置业务的id生成,虽然推荐使用【推荐】方式配置,但仍旧提供了对应的支持。
1 2 3 4
@Autowired DidLoader didLoader; this.didLoader.follow("redis", businessName);
高级使用
BusinessURI
在【推荐】中看到了如下的配置
|
|
这是一种基于BusinessURI
的配置方式。与标准URI
语法完全一致,只是具体含义有些差异。以redis://abc
举例:
-
URI
之Schema
示例中的
redis
即就是URI的Schema,在BusinessURI
中,其对应着使用的具体IdEngine
。比如redis
即会使用engineName
为redis
的IDEngine。默认可用的Schema有redis
,zookeeper
,uuid
分别对应着RedisIDEngine
,ZookeeperIdEngine
,UuidEngine
。 -
URI
之Host
示例中的
abc
即就是URI的Host,在BusinessURI
中,其对应着follow的businessName
。这也是didLoader.next(businessName);
的基础。
自定义IdEngine
org.openingo.spring.extension.gedid.engine.IDidEngine
定义了实现一个IdEngine的基本要素
|
|
engineName()可以随意定义除了默认Schema之外的任意的名称。
自定义IdEngine示例
|
|
此处示例,以UUID为例。特别注意,自定义示例需要注入到SpringIoC才可以正常使用。
配置自定义IdEngine
|
|
使用
qicz
引擎follow业务business-abcd
。
结语
至此,关于的GeDid目前的所有都在这里了。后续有变动将在本文中陆续更新。