分布式ID生成器-GeDid
源起
尝试设计实现一个分布式id工具,已是好几年前的事了,这里是历史的痕迹。
最初实现了基于redis(jedis客户端)的版本,而后在19年左右,考虑接入Zookeeper版本的。但是一直没有着手去做。
最近借助一次"翻新"的机会,把它又拿出来,考虑完成Zookeeper版本的实现。因spring-boot-x已经有了很多的基础,也便于Gedid在springboot环境下使用,与springboot的整合和利用已有的springboot资源,所以考虑把Gedid迁移至spring-boot-x,以至于进行了大量的改造。多次调整之后,变有了现在的结果。也有了这个文章的整理。
这个文章目的:把Gedid的使用场景和使用方式道明白。
开始
引入依赖
|
|
在启动类上加入
@EnableExtension
目前最新版本
ID引擎
目前支持引擎如下:
-
EtcdIdEnginesince v4.3.0 [ 2021.7.3更新 ]- 基于
PutResponse的Prev_Kv的version; - 对应的id类型是
Long; - 支持业务隔离,对应的
businessName就是业务的标识; - 使用
jetcd客户端; etcd存储的数据key格式为:"gedid-{businessName}",可以通过此查询对应的数据; since v4.3.1
- 基于
-
SnowflakeIdEnginesince 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 7openingo: 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 12openingo: 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目前的所有都在这里了。后续有变动将在本文中陆续更新。