From e78442ed9c167c85d6bef61bc37a00749126093f Mon Sep 17 00:00:00 2001 From: caojiajun Date: Fri, 6 Dec 2024 17:03:35 +0800 Subject: [PATCH] docs: update (#325) --- README.md | 2 +- .../quick-start-java-segment.md | 44 +++++ .../quick-start-java-snowflake.md | 54 ++++++ .../quick-start-java-strict.md | 49 ++++++ ...quick-start-spring-boot-starter-segment.md | 59 +++++++ ...ick-start-spring-boot-starter-snowflake.md | 65 +++++++ .../quick-start-spring-boot-starter-strict.md | 87 ++++++++++ docs/camellia-id-gen/segment.md | 151 ++++------------- docs/camellia-id-gen/snowflake.md | 141 ++-------------- docs/camellia-id-gen/strict.md | 159 ++---------------- docs/camellia-id-gen/strict2.md | 3 +- .../other/camellia-redis-proxy-bootstrap.md | 4 +- 12 files changed, 425 insertions(+), 393 deletions(-) create mode 100644 docs/camellia-id-gen/quick-start-java-segment.md create mode 100644 docs/camellia-id-gen/quick-start-java-snowflake.md create mode 100644 docs/camellia-id-gen/quick-start-java-strict.md create mode 100644 docs/camellia-id-gen/quick-start-spring-boot-starter-segment.md create mode 100644 docs/camellia-id-gen/quick-start-spring-boot-starter-snowflake.md create mode 100644 docs/camellia-id-gen/quick-start-spring-boot-starter-strict.md diff --git a/README.md b/README.md index 7874ebb3b..66546306c 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Camellia提供了一系列简单易用的服务器组件,包括但不限于: * 支持使用http协议访问proxy,类似于 [webdis](https://github.com/nicolasff/webdis) ,但是接口定义不一样,具体见:[redis_over_http](/docs/camellia-redis-proxy/other/redis_over_http.md) * 支持自定义分片、读写分离、双(多)写、双(多)读 * 支持多租户(可以同时代理多组路由,可以通过不同的登录密码来区分) -* 支持多租户动态路由,支持自定义的动态路由数据源(内置:本地配置文件、nacos、etcd等,也可以自定义) +* 支持动态路由,支持自定义的动态路由数据源(内置:本地配置文件、nacos、etcd等,也可以自定义) * 支持读从节点(redis-sentinel、redis-cluster都支持) * 高可用,可以基于lb组成集群,也可以基于注册中心组成集群,也可以伪装成redis-cluster组成集群,也可以伪装成redis-sentinel组成集群 * 支持自定义插件,并且内置了很多插件,可以按需使用(包括:大key监控、热key监控、热key缓存、key命名空间、ip黑白名单、速率控制等等) diff --git a/docs/camellia-id-gen/quick-start-java-segment.md b/docs/camellia-id-gen/quick-start-java-segment.md new file mode 100644 index 000000000..e16413a16 --- /dev/null +++ b/docs/camellia-id-gen/quick-start-java-segment.md @@ -0,0 +1,44 @@ + +引入maven依赖 +``` + + com.netease.nim + camellia-id-gen-core + 1.3.0 + +``` +示例如下: +```java +public class CamelliaSegmentIdGenTest { + + private static final AtomicLong id = new AtomicLong(); + + public static void main(String[] args) throws Exception { + CamelliaSegmentIdGenConfig config = new CamelliaSegmentIdGenConfig(); + config.setStep(1000);//每次从数据库获取一批id时的批次大小 + config.setTagCount(1000);//服务包括的tag数量,会缓存在本地内存,如果实际tag数超过本配置,会导致本地内存被驱逐,进而丢失部分id段,丢失后会穿透到数据库) + config.setMaxRetry(10);//当并发请求过来时,只会让一次请求穿透到db,其他请求会等待并重试,本配置表示重试的次数 + config.setRetryIntervalMillis(10);//当并发请求过来时,只会让一次请求穿透到db,其他请求会等待并重试,表示重试间隔 + config.setRegionBits(0);//region比特位,0表示不区分单元 + config.setRegionId(0);//regionId,如果regionBits为0,则regionId必须为0 + + //设置IdLoader,可以使用数据库实现 + config.setIdLoader((tag, step) -> { + IDRange idRange = new IDRange(id.get() + 1, id.addAndGet(step)); + System.out.println("load [" + idRange.getStart() + "-" + idRange.getEnd() + "] in " + Thread.currentThread().getName()); + return idRange; + }); + CamelliaSegmentIdGen idGen = new CamelliaSegmentIdGen(config); + int i=2000; + while (i -- > 0) { + //可以获取一批 + System.out.println(idGen.genIds("tag", 3)); +// Thread.sleep(1000); + //也可以获取一个 + System.out.println(idGen.genId("tag")); +// Thread.sleep(1000); + } + } +} + +``` \ No newline at end of file diff --git a/docs/camellia-id-gen/quick-start-java-snowflake.md b/docs/camellia-id-gen/quick-start-java-snowflake.md new file mode 100644 index 000000000..30c03111d --- /dev/null +++ b/docs/camellia-id-gen/quick-start-java-snowflake.md @@ -0,0 +1,54 @@ + +引入maven依赖 +``` + + com.netease.nim + camellia-id-gen-core + 1.3.0 + +``` +示例如下: +```java +public class CamelliaSnowflakeIdGenTest { + + public static void main(String[] args) { + CamelliaSnowflakeConfig config = new CamelliaSnowflakeConfig(); + config.setRegionBits(0);//单元id所占的比特位数,0表示不区分单元 + config.setRegionId(0);//regionId,如果regionBits为0,则regionId必须为0 + config.setWorkerIdBits(10);//workerId所占的比特位数 + config.setSequenceBits(12);//序列号所占比特位数 + //使用redis生成workerId + config.setWorkerIdGen(new RedisWorkerIdGen(new CamelliaRedisTemplate("redis://@127.0.0.1:6379"))); + + CamelliaSnowflakeIdGen idGen = new CamelliaSnowflakeIdGen(config); + + int i=2000; + while (i -- > 0) { + long id = idGen.genId();//生成id + System.out.println(id); + System.out.println(Long.toBinaryString(id)); + System.out.println(Long.toBinaryString(id).length()); + long ts = idGen.decodeTs(id);//从id中解析出时间戳 + System.out.println(ts); + System.out.println(new Date(ts)); + } + + long target = 1000*10000; + int j = 0; + long start = System.currentTimeMillis(); + while (true) { + idGen.genId(); + j++; + if (j % 100000 == 0) { + System.out.println("i=" + j); + } + if (j >= target) break; + } + long end = System.currentTimeMillis(); + System.out.println("QPS=" + (target / ((end - start)/1000.0))); + //###idea里直接运行的简单测试结果: + //QPS=4061738.424045491 + } +} + +``` \ No newline at end of file diff --git a/docs/camellia-id-gen/quick-start-java-strict.md b/docs/camellia-id-gen/quick-start-java-strict.md new file mode 100644 index 000000000..a7077b283 --- /dev/null +++ b/docs/camellia-id-gen/quick-start-java-strict.md @@ -0,0 +1,49 @@ + +引入maven依赖 +``` + + com.netease.nim + camellia-id-gen-core + 1.3.0 + +``` +示例如下: +```java +public class CamelliaStrictIdGenTest { + + private static final AtomicLong id = new AtomicLong(); + + public static void main(String[] args) { + CamelliaStrictIdGenConfig config = new CamelliaStrictIdGenConfig(); + + config.setCacheKeyPrefix("strict");//redis key的前缀 + config.setDefaultStep(10);//默认每次从db获取的id个数,也是最小的个数 + config.setMaxStep(100);//根据id的消耗速率动态调整每次从db获取id的个数,这个是上限值 + config.setLockExpireMillis(3000);//redis缓存里id耗尽时需要穿透到db重新获取,为了控制并发需要一个分布式锁,这是分布式锁的超时时间 + config.setCacheExpireSeconds(3600*24);//id缓存在redis里,redis key的过期时间,默认1天 + config.setCacheHoldSeconds(10);//缓存里的id如果在短时间内被消耗完,则下次获取id时需要多获取一些,本配置是触发step调整的阈值 + config.setRegionBits(0);//单元id所占的比特位数,0表示不区分单元 + config.setRegionId(0);//regionId,如果regionBits为0,则regionId必须为0 + config.setMaxRetry(1000);//缓存中id耗尽时穿透到db,其他线程等待重试的最大次数 + config.setRetryIntervalMillis(5);//缓存中id耗尽时穿透到db,其他线程等待重试的间隔 + + //设置redis template + config.setTemplate(new CamelliaRedisTemplate("redis://@127.0.0.1:6379")); + //设置IdLoader,可以使用数据库实现 + config.setIdLoader((tag, step) -> { + IDRange idRange = new IDRange(id.get() + 1, id.addAndGet(step)); + System.out.println("load [" + idRange.getStart() + "," + idRange.getEnd() + "] in " + Thread.currentThread().getName()); + return idRange; + }); + + CamelliaStrictIdGen idGen = new CamelliaStrictIdGen(config); + int i=2000; + while (i -- > 0) { + //可以获取最新的id,但是不使用 + System.out.println("peek, id = " + idGen.peekId("tag")); + //获取最新的id + System.out.println("get, id = " + idGen.genId("tag")); + } + } +} +``` \ No newline at end of file diff --git a/docs/camellia-id-gen/quick-start-spring-boot-starter-segment.md b/docs/camellia-id-gen/quick-start-spring-boot-starter-segment.md new file mode 100644 index 000000000..9a0f9c948 --- /dev/null +++ b/docs/camellia-id-gen/quick-start-spring-boot-starter-segment.md @@ -0,0 +1,59 @@ + + +使用spring-boot-starter方式下,默认使用数据库来生成id +引入maven依赖 +``` + + com.netease.nim + camellia-id-gen-segment-spring-boot-starter + 1.3.0 + + + com.netease.nim + camellia-id-gen-id-loader + 1.3.0 + +``` +编写启动类: +```java +@SpringBootApplication +@ComponentScan(basePackages = {"com.netease.nim.camellia.id.gen.springboot.segment", "com.netease.nim.camellia.id.gen.springboot.idloader"}) +@MapperScan("com.netease.nim.camellia.id.gen.springboot.idloader") +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class); + } +} + +``` +配置application.yml +```yaml +server: + port: 8083 +spring: + application: + name: camellia-id-gen-segment + datasource: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=false + username: root + password: root + hikari: + minimum-idle: 5 + idle-timeout: 180000 + maximum-pool-size: 10 + connection-timeout: 30000 + connection-test-query: SELECT 1 + + +camellia-id-gen-segment: + region-bits: 0 #region比特位,0表示不区分单元 + region-id: 0 #regionId,如果regionBits为0,则regionId必须为0 + region-id-shifting-bits: 0 #regionId左移多少位 + tag-count: 1000 #服务包括的tag数量,会缓存在本地内存,如果实际tag数超过本配置,会导致本地内存被驱逐,进而丢失部分id段,丢失后会穿透到数据库) + step: 1000 #每次从数据库获取一批id时的批次大小 + max-retry: 500 #当并发请求过来时,只会让一次请求穿透到db,其他请求会等待并重试,本配置表示重试的次数 + retry-interval-millis: 10 #当并发请求过来时,只会让一次请求穿透到db,其他请求会等待并重试,表示重试间隔 +``` \ No newline at end of file diff --git a/docs/camellia-id-gen/quick-start-spring-boot-starter-snowflake.md b/docs/camellia-id-gen/quick-start-spring-boot-starter-snowflake.md new file mode 100644 index 000000000..85019e4b3 --- /dev/null +++ b/docs/camellia-id-gen/quick-start-spring-boot-starter-snowflake.md @@ -0,0 +1,65 @@ + +引入maven依赖 +``` + + + com.netease.nim + camellia-id-gen-snowflake-spring-boot-starter + 1.3.0 + + + com.netease.nim + camellia-redis-spring-boot3-starter + 1.3.0 + + +``` +编写启动类: +```java +@SpringBootApplication +@ComponentScan(basePackages = {"com.netease.nim.camellia.id.gen.springboot.snowflake"}) +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class); + } +} +``` +配置application.yml +```yaml +server: + port: 8081 +spring: + application: + name: camellia-id-gen-snowflake +camellia-id-gen-snowflake: + sequence-bits: 12 #序列号所占比特位数 + worker-id-bits: 10 #workerId所占的比特位数 + region-bits: 0 #单元id所占的比特位数,0表示不区分单元 + region-id: 0 #regionId,如果regionBits为0,则regionId必须为0 + worker-id: -1 #-1表示使用redis生成workerId + redis-worker-id-gen-conf: + namespace: camellia #使用redis生成workerId时不同的命名空间下,workerId生成互不干扰 + lock-expire-millis: 3000 #使用redis生成workerId时获取分布式锁时的超时时间 + renew-interval-millis: 1000 #使用redis生成workerId时续约workerId的间隔 + exit-if-renew-fail: false #如果续约失败(可能redis超时了,或者gc导致workerId被其他进程抢走了,概率较低),是否进程退出,默认false + + +camellia-redis: + type: local + local: + resource: redis://@127.0.0.1:6379 + redis-conf: + jedis: + timeout: 2000 + min-idle: 0 + max-idle: 32 + max-active: 32 + max-wait-millis: 2000 + jedis-cluster: + max-wait-millis: 2000 + min-idle: 0 + max-idle: 8 + max-active: 16 + max-attempts: 5 + timeout: 2000 +``` \ No newline at end of file diff --git a/docs/camellia-id-gen/quick-start-spring-boot-starter-strict.md b/docs/camellia-id-gen/quick-start-spring-boot-starter-strict.md new file mode 100644 index 000000000..38fe025a9 --- /dev/null +++ b/docs/camellia-id-gen/quick-start-spring-boot-starter-strict.md @@ -0,0 +1,87 @@ + +引入maven依赖 +``` + + com.netease.nim + camellia-id-gen-strict-spring-boot-starter + 1.3.0 + + + com.netease.nim + camellia-id-gen-id-loader + 1.3.0 + + + com.netease.nim + camellia-redis-spring-boot3-starter + 1.3.0 + +``` +编写启动类: +```java +@SpringBootApplication +@ComponentScan(basePackages = {"com.netease.nim.camellia.id.gen.springboot.segment", "com.netease.nim.camellia.id.gen.springboot.idloader"}) +@MapperScan("com.netease.nim.camellia.id.gen.springboot.idloader") +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class); + } +} + +``` +配置application.yml +```yaml +server: + port: 8082 +spring: + application: + name: camellia-id-gen-segment + datasource: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=false + username: root + password: root + hikari: + minimum-idle: 5 + idle-timeout: 180000 + maximum-pool-size: 10 + connection-timeout: 30000 + connection-test-query: SELECT 1 + + +camellia-id-gen-strict: + region-bits: 0 #单元id所占的比特位数,0表示不区分单元 + region-id: 0 #regionId,如果regionBits为0,则regionId必须为0 + region-id-shifting-bits: 0 #regionId左移多少位 + cache-key-prefix: strict #redis key的前缀 + lock-expire-millis: 3000 #redis缓存里id耗尽时需要穿透到db重新获取,为了控制并发需要一个分布式锁,这是分布式锁的超时时间 + cache-expire-seconds: 86400 #id缓存在redis里,redis key的过期时间,默认1天 + cache-hold-seconds: 10 #缓存里的id如果在短时间内被消耗完,则下次获取id时需要多获取一些,本配置是触发step调整的阈值 + max-retry: 1000 #缓存中id耗尽时穿透到db,其他线程等待重试的最大次数 + retry-interval-millis: 5 #缓存中id耗尽时穿透到db,其他线程等待重试的间隔 + default-step: 10 #默认每次从db获取的id个数,也是最小的个数 + max-step: 100 #根据id的消耗速率动态调整每次从db获取id的个数,这个是上限值 + + + +camellia-redis: + type: local + local: + resource: redis://@127.0.0.1:6379 + redis-conf: + jedis: + timeout: 2000 + min-idle: 0 + max-idle: 32 + max-active: 32 + max-wait-millis: 2000 + jedis-cluster: + max-wait-millis: 2000 + min-idle: 0 + max-idle: 8 + max-active: 16 + max-attempts: 5 + timeout: 2000 +``` \ No newline at end of file diff --git a/docs/camellia-id-gen/segment.md b/docs/camellia-id-gen/segment.md index b9a728715..cfe1ec26c 100644 --- a/docs/camellia-id-gen/segment.md +++ b/docs/camellia-id-gen/segment.md @@ -17,109 +17,13 @@ ### id构成(二进制,设置了regionId且设置了regionId左移的情况下) -### 用法(直接使用) -引入maven依赖 -``` - - com.netease.nim - camellia-id-gen-core - 1.3.0 - -``` -示例如下: -```java -public class CamelliaSegmentIdGenTest { - - private static final AtomicLong id = new AtomicLong(); - - public static void main(String[] args) throws Exception { - CamelliaSegmentIdGenConfig config = new CamelliaSegmentIdGenConfig(); - config.setStep(1000);//每次从数据库获取一批id时的批次大小 - config.setTagCount(1000);//服务包括的tag数量,会缓存在本地内存,如果实际tag数超过本配置,会导致本地内存被驱逐,进而丢失部分id段,丢失后会穿透到数据库) - config.setMaxRetry(10);//当并发请求过来时,只会让一次请求穿透到db,其他请求会等待并重试,本配置表示重试的次数 - config.setRetryIntervalMillis(10);//当并发请求过来时,只会让一次请求穿透到db,其他请求会等待并重试,表示重试间隔 - config.setRegionBits(0);//region比特位,0表示不区分单元 - config.setRegionId(0);//regionId,如果regionBits为0,则regionId必须为0 - - //设置IdLoader,可以使用数据库实现 - config.setIdLoader((tag, step) -> { - IDRange idRange = new IDRange(id.get() + 1, id.addAndGet(step)); - System.out.println("load [" + idRange.getStart() + "-" + idRange.getEnd() + "] in " + Thread.currentThread().getName()); - return idRange; - }); - CamelliaSegmentIdGen idGen = new CamelliaSegmentIdGen(config); - int i=2000; - while (i -- > 0) { - //可以获取一批 - System.out.println(idGen.genIds("tag", 3)); -// Thread.sleep(1000); - //也可以获取一个 - System.out.println(idGen.genId("tag")); -// Thread.sleep(1000); - } - } -} - -``` - -### 用法(使用spring-boot-starter) -使用spring-boot-starter方式下,默认使用数据库来生成id -引入maven依赖 -``` - - com.netease.nim - camellia-id-gen-segment-spring-boot-starter - 1.3.0 - - - com.netease.nim - camellia-id-gen-id-loader - 1.3.0 - -``` -编写启动类: -```java -@SpringBootApplication -@ComponentScan(basePackages = {"com.netease.nim.camellia.id.gen.springboot.segment", "com.netease.nim.camellia.id.gen.springboot.idloader"}) -@MapperScan("com.netease.nim.camellia.id.gen.springboot.idloader") -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class); - } -} - -``` -配置application.yml -```yaml -server: - port: 8083 -spring: - application: - name: camellia-id-gen-segment - datasource: - type: com.zaxxer.hikari.HikariDataSource - driver-class-name: com.mysql.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=false - username: root - password: root - hikari: - minimum-idle: 5 - idle-timeout: 180000 - maximum-pool-size: 10 - connection-timeout: 30000 - connection-test-query: SELECT 1 +### 快速部署一(使用安装包部署独立服务) +具体见:[quick-start-package](quick-start-package-segment.md) +### 快速部署二(使用spring-boot-starter部署独立服务) +具体见:[quick-start-spring-boot](quick-start-spring-boot-starter-segment.md) -camellia-id-gen-segment: - region-bits: 0 #region比特位,0表示不区分单元 - region-id: 0 #regionId,如果regionBits为0,则regionId必须为0 - region-id-shifting-bits: 0 #regionId左移多少位 - tag-count: 1000 #服务包括的tag数量,会缓存在本地内存,如果实际tag数超过本配置,会导致本地内存被驱逐,进而丢失部分id段,丢失后会穿透到数据库) - step: 1000 #每次从数据库获取一批id时的批次大小 - max-retry: 500 #当并发请求过来时,只会让一次请求穿透到db,其他请求会等待并重试,本配置表示重试的次数 - retry-interval-millis: 10 #当并发请求过来时,只会让一次请求穿透到db,其他请求会等待并重试,表示重试间隔 -``` +### 数据库 数据库建表语句: ```sql CREATE TABLE `camellia_id_info` ( @@ -130,8 +34,10 @@ CREATE TABLE `camellia_id_info` ( PRIMARY KEY (`tag`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='id生成表'; ``` -启动后访问相关接口: -返回一个id: + +### api接口 + +#### 返回一个id(GET请求) http://127.0.0.1:8083/camellia/id/gen/segment/genId?tag=a 返回示例: ```json @@ -141,7 +47,7 @@ http://127.0.0.1:8083/camellia/id/gen/segment/genId?tag=a "msg": "success" } ``` -返回多个id: +#### 返回多个id(GET请求) http://127.0.0.1:8083/camellia/id/gen/segment/genIds?tag=a&count=3 返回示例: ```json @@ -155,23 +61,15 @@ http://127.0.0.1:8083/camellia/id/gen/segment/genIds?tag=a&count=3 "msg": "success" } ``` -更新id起始值(POST请求): + +#### 更新id起始值(POST请求) ``` curl -d "tag=a&id=100" http://127.0.0.1:8083/camellia/id/gen/segment/update ``` -当使用spring-boot-starter部署了独立的发号器服务后,为了方便使用http方法访问相关接口,我们提供了一个封装sdk(sdk支持缓存id用于提高性能) -先引入maven依赖: -``` - - com.netease.nim - camellia-id-gen-sdk - 1.3.0 - -``` -解析regionId: +#### 解析regionId(GET请求) http://127.0.0.1:8083/camellia/id/gen/segment/decodeRegionId?id=11111 -返回示例: +返回示例: ```json { "code": 200, @@ -180,6 +78,20 @@ http://127.0.0.1:8083/camellia/id/gen/segment/decodeRegionId?id=11111 } ``` +### 使用java-sdk访问api接口 + +当部署了独立的发号器服务后,为了方便使用http方法访问相关接口,我们提供了一个封装sdk(sdk支持缓存id用于提高性能) + +先引入maven依赖: +``` + + com.netease.nim + camellia-id-gen-sdk + 1.3.0 + +``` + + 示例代码如下: ```java public class CamelliaSegmentIdGenSdkTest { @@ -250,7 +162,7 @@ camellia-id-gen-segment: # - test4 ``` -如果希望手动触发一次同步,可以调用接口: +如果希望手动触发一次同步,可以调用接口(GET): http://127.0.0.1:8083/camellia/id/gen/segment/sync 返回示例: ```json @@ -261,7 +173,6 @@ http://127.0.0.1:8083/camellia/id/gen/segment/sync } ``` -### 使用安装包启动发号器服务 -具体见:[quick-start-package](quick-start-package-segment.md) - +### 如果你不想部署独立服务 +则可以直接本地发号,具体见:[quick-start-java](quick-start-java-segment.md) \ No newline at end of file diff --git a/docs/camellia-id-gen/snowflake.md b/docs/camellia-id-gen/snowflake.md index 0372c8be2..abc49685a 100644 --- a/docs/camellia-id-gen/snowflake.md +++ b/docs/camellia-id-gen/snowflake.md @@ -17,127 +17,16 @@ ### id构成(二进制) -### 用法(直接使用) -引入maven依赖 -``` - - com.netease.nim - camellia-id-gen-core - 1.3.0 - -``` -示例如下: -```java -public class CamelliaSnowflakeIdGenTest { +### 快速部署一(使用安装包部署独立服务) +具体见:[quick-start-package](quick-start-package-snowflake.md) - public static void main(String[] args) { - CamelliaSnowflakeConfig config = new CamelliaSnowflakeConfig(); - config.setRegionBits(0);//单元id所占的比特位数,0表示不区分单元 - config.setRegionId(0);//regionId,如果regionBits为0,则regionId必须为0 - config.setWorkerIdBits(10);//workerId所占的比特位数 - config.setSequenceBits(12);//序列号所占比特位数 - //使用redis生成workerId - config.setWorkerIdGen(new RedisWorkerIdGen(new CamelliaRedisTemplate("redis://@127.0.0.1:6379"))); - - CamelliaSnowflakeIdGen idGen = new CamelliaSnowflakeIdGen(config); - - int i=2000; - while (i -- > 0) { - long id = idGen.genId();//生成id - System.out.println(id); - System.out.println(Long.toBinaryString(id)); - System.out.println(Long.toBinaryString(id).length()); - long ts = idGen.decodeTs(id);//从id中解析出时间戳 - System.out.println(ts); - System.out.println(new Date(ts)); - } +### 快速部署二(使用spring-boot-starter部署独立服务) +具体见:[quick-start-spring-boot](quick-start-spring-boot-starter-snowflake.md) - long target = 1000*10000; - int j = 0; - long start = System.currentTimeMillis(); - while (true) { - idGen.genId(); - j++; - if (j % 100000 == 0) { - System.out.println("i=" + j); - } - if (j >= target) break; - } - long end = System.currentTimeMillis(); - System.out.println("QPS=" + (target / ((end - start)/1000.0))); - //###idea里直接运行的简单测试结果: - //QPS=4061738.424045491 - } -} -``` +### api接口 -### 用法(使用spring-boot-starter) -引入maven依赖 -``` - - - com.netease.nim - camellia-id-gen-snowflake-spring-boot-starter - 1.3.0 - - - com.netease.nim - camellia-redis-spring-boot-starter - 1.3.0 - - -``` -编写启动类: -```java -@SpringBootApplication -@ComponentScan(basePackages = {"com.netease.nim.camellia.id.gen.springboot.snowflake"}) -public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class); - } -} -``` -配置application.yml -```yaml -server: - port: 8081 -spring: - application: - name: camellia-id-gen-snowflake -camellia-id-gen-snowflake: - sequence-bits: 12 #序列号所占比特位数 - worker-id-bits: 10 #workerId所占的比特位数 - region-bits: 0 #单元id所占的比特位数,0表示不区分单元 - region-id: 0 #regionId,如果regionBits为0,则regionId必须为0 - worker-id: -1 #-1表示使用redis生成workerId - redis-worker-id-gen-conf: - namespace: camellia #使用redis生成workerId时不同的命名空间下,workerId生成互不干扰 - lock-expire-millis: 3000 #使用redis生成workerId时获取分布式锁时的超时时间 - renew-interval-millis: 1000 #使用redis生成workerId时续约workerId的间隔 - exit-if-renew-fail: false #如果续约失败(可能redis超时了,或者gc导致workerId被其他进程抢走了,概率较低),是否进程退出,默认false - - -camellia-redis: - type: local - local: - resource: redis://@127.0.0.1:6379 - redis-conf: - jedis: - timeout: 2000 - min-idle: 0 - max-idle: 32 - max-active: 32 - max-wait-millis: 2000 - jedis-cluster: - max-wait-millis: 2000 - min-idle: 0 - max-idle: 8 - max-active: 16 - max-attempts: 5 - timeout: 2000 -``` -启动后访问: +#### 返回一个id(GET请求) http://127.0.0.1:8081/camellia/id/gen/snowflake/genId 返回示例: ```json @@ -147,7 +36,8 @@ http://127.0.0.1:8081/camellia/id/gen/snowflake/genId "msg": "success" } ``` -此外还提供了一个解析时间戳的接口: + +#### 解析时间戳(GET请求) http://127.0.0.1:8081/camellia/id/gen/snowflake/decodeTs?id=6393964107649080 返回示例: ```json @@ -158,7 +48,7 @@ http://127.0.0.1:8081/camellia/id/gen/snowflake/decodeTs?id=6393964107649080 } ``` -解析regionId: +#### 解析regionId(GET请求) http://127.0.0.1:8081/camellia/id/gen/snowflake/decodeRegionId?id=11111 返回示例: ```json @@ -169,7 +59,7 @@ http://127.0.0.1:8081/camellia/id/gen/snowflake/decodeRegionId?id=11111 } ``` -解析workerId: +#### 解析workerId(GET请求) http://127.0.0.1:8081/camellia/id/gen/snowflake/decodeWorkerId?id=11111 返回示例: ```json @@ -180,7 +70,7 @@ http://127.0.0.1:8081/camellia/id/gen/snowflake/decodeWorkerId?id=11111 } ``` -解析sequence: +#### 解析sequence(GET请求) http://127.0.0.1:8081/camellia/id/gen/snowflake/decodeSequence?id=11111 返回示例: ```json @@ -191,13 +81,14 @@ http://127.0.0.1:8081/camellia/id/gen/snowflake/decodeSequence?id=11111 } ``` -当使用spring-boot-starter部署了独立的发号器服务后,为了方便使用http方法访问相关接口,我们提供了一个简易的封装 +### 使用java-sdk访问api接口 + 先引入maven依赖: ``` com.netease.nim camellia-id-gen-sdk - a.b.c + 1.3.0 ``` 示例代码如下: @@ -235,6 +126,6 @@ public class CamelliaSnowflakeIdGenSdkTest { ``` -### 使用安装包启动发号器服务 -具体见:[quick-start-package](quick-start-package-snowflake.md) +### 如果你不想部署独立服务 +则可以直接本地发号,具体见:[quick-start-java](quick-start-java-snowflake.md) \ No newline at end of file diff --git a/docs/camellia-id-gen/strict.md b/docs/camellia-id-gen/strict.md index 4cab22cec..e079287ac 100644 --- a/docs/camellia-id-gen/strict.md +++ b/docs/camellia-id-gen/strict.md @@ -19,145 +19,14 @@ ### id构成(二进制,设置了regionId且设置了regionId左移的情况下) -### 用法(直接使用) -引入maven依赖 -``` - - com.netease.nim - camellia-id-gen-core - 1.3.0 - -``` -示例如下: -```java -public class CamelliaStrictIdGenTest { - - private static final AtomicLong id = new AtomicLong(); +### 快速部署一(使用安装包部署独立服务) +具体见:[quick-start-package](quick-start-package-strict.md) - public static void main(String[] args) { - CamelliaStrictIdGenConfig config = new CamelliaStrictIdGenConfig(); - - config.setCacheKeyPrefix("strict");//redis key的前缀 - config.setDefaultStep(10);//默认每次从db获取的id个数,也是最小的个数 - config.setMaxStep(100);//根据id的消耗速率动态调整每次从db获取id的个数,这个是上限值 - config.setLockExpireMillis(3000);//redis缓存里id耗尽时需要穿透到db重新获取,为了控制并发需要一个分布式锁,这是分布式锁的超时时间 - config.setCacheExpireSeconds(3600*24);//id缓存在redis里,redis key的过期时间,默认1天 - config.setCacheHoldSeconds(10);//缓存里的id如果在短时间内被消耗完,则下次获取id时需要多获取一些,本配置是触发step调整的阈值 - config.setRegionBits(0);//单元id所占的比特位数,0表示不区分单元 - config.setRegionId(0);//regionId,如果regionBits为0,则regionId必须为0 - config.setMaxRetry(1000);//缓存中id耗尽时穿透到db,其他线程等待重试的最大次数 - config.setRetryIntervalMillis(5);//缓存中id耗尽时穿透到db,其他线程等待重试的间隔 - - //设置redis template - config.setTemplate(new CamelliaRedisTemplate("redis://@127.0.0.1:6379")); - //设置IdLoader,可以使用数据库实现 - config.setIdLoader((tag, step) -> { - IDRange idRange = new IDRange(id.get() + 1, id.addAndGet(step)); - System.out.println("load [" + idRange.getStart() + "," + idRange.getEnd() + "] in " + Thread.currentThread().getName()); - return idRange; - }); - - CamelliaStrictIdGen idGen = new CamelliaStrictIdGen(config); - int i=2000; - while (i -- > 0) { - //可以获取最新的id,但是不使用 - System.out.println("peek, id = " + idGen.peekId("tag")); - //获取最新的id - System.out.println("get, id = " + idGen.genId("tag")); - } - } -} -``` - -### 用法(使用spring-boot-starter) -使用spring-boot-starter方式下,默认使用数据库来生成id -引入maven依赖 -``` - - com.netease.nim - camellia-id-gen-strict-spring-boot-starter - 1.3.0 - - - com.netease.nim - camellia-id-gen-id-loader - 1.3.0 - - - com.netease.nim - camellia-redis-spring-boot-starter - 1.3.0 - -``` -编写启动类: -```java -@SpringBootApplication -@ComponentScan(basePackages = {"com.netease.nim.camellia.id.gen.springboot.segment", "com.netease.nim.camellia.id.gen.springboot.idloader"}) -@MapperScan("com.netease.nim.camellia.id.gen.springboot.idloader") -public class Application { +### 快速部署二(使用spring-boot-starter部署独立服务) +具体见:[quick-start-spring-boot](quick-start-spring-boot-starter-strict.md) - public static void main(String[] args) { - SpringApplication.run(Application.class); - } -} +### 数据库建表语句 -``` -配置application.yml -```yaml -server: - port: 8082 -spring: - application: - name: camellia-id-gen-segment - datasource: - type: com.zaxxer.hikari.HikariDataSource - driver-class-name: com.mysql.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=false - username: root - password: root - hikari: - minimum-idle: 5 - idle-timeout: 180000 - maximum-pool-size: 10 - connection-timeout: 30000 - connection-test-query: SELECT 1 - - -camellia-id-gen-strict: - region-bits: 0 #单元id所占的比特位数,0表示不区分单元 - region-id: 0 #regionId,如果regionBits为0,则regionId必须为0 - region-id-shifting-bits: 0 #regionId左移多少位 - cache-key-prefix: strict #redis key的前缀 - lock-expire-millis: 3000 #redis缓存里id耗尽时需要穿透到db重新获取,为了控制并发需要一个分布式锁,这是分布式锁的超时时间 - cache-expire-seconds: 86400 #id缓存在redis里,redis key的过期时间,默认1天 - cache-hold-seconds: 10 #缓存里的id如果在短时间内被消耗完,则下次获取id时需要多获取一些,本配置是触发step调整的阈值 - max-retry: 1000 #缓存中id耗尽时穿透到db,其他线程等待重试的最大次数 - retry-interval-millis: 5 #缓存中id耗尽时穿透到db,其他线程等待重试的间隔 - default-step: 10 #默认每次从db获取的id个数,也是最小的个数 - max-step: 100 #根据id的消耗速率动态调整每次从db获取id的个数,这个是上限值 - - - -camellia-redis: - type: local - local: - resource: redis://@127.0.0.1:6379 - redis-conf: - jedis: - timeout: 2000 - min-idle: 0 - max-idle: 32 - max-active: 32 - max-wait-millis: 2000 - jedis-cluster: - max-wait-millis: 2000 - min-idle: 0 - max-idle: 8 - max-active: 16 - max-attempts: 5 - timeout: 2000 -``` -数据库建表语句: ```sql CREATE TABLE `camellia_id_info` ( `tag` varchar(512) NOT NULL COMMENT 'tag', @@ -167,8 +36,9 @@ CREATE TABLE `camellia_id_info` ( PRIMARY KEY (`tag`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='id生成表'; ``` -启动后访问相关接口: -返回一个id: + +### api接口 +#### 返回一个id(GET请求) http://127.0.0.1:8082/camellia/id/gen/strict/genId?tag=a 返回示例: ```json @@ -178,7 +48,8 @@ http://127.0.0.1:8082/camellia/id/gen/strict/genId?tag=a "msg": "success" } ``` -返回最新的id,但是不使用: + +#### 返回最新的id,但是不使用(GET请求) http://127.0.0.1:8082/camellia/id/gen/strict/peekId?tag=a 返回示例: ```json @@ -188,12 +59,12 @@ http://127.0.0.1:8082/camellia/id/gen/strict/peekId?tag=a "msg": "success" } ``` -更新id起始值(POST请求): +#### 更新id起始值(POST请求) ``` curl -d "tag=a&id=100" http://127.0.0.1:8082/camellia/id/gen/strict/update ``` -解析regionId: +#### 解析regionId(GET请求) http://127.0.0.1:8082/camellia/id/gen/strict/decodeRegionId?id=11111 返回示例: ```json @@ -204,7 +75,8 @@ http://127.0.0.1:8082/camellia/id/gen/strict/decodeRegionId?id=11111 } ``` -当使用spring-boot-starter部署了独立的发号器服务后,为了方便使用http方法访问相关接口,我们提供了一个简易的封装 +### 使用java-sdk访问api接口 + 先引入maven依赖: ``` @@ -243,7 +115,6 @@ public class CamelliaStrictIdGenSdkTest { } ``` -### 使用安装包启动发号器服务 -具体见:[quick-start-package](quick-start-package-strict.md) + diff --git a/docs/camellia-id-gen/strict2.md b/docs/camellia-id-gen/strict2.md index 5e5be7b89..e66d2a898 100644 --- a/docs/camellia-id-gen/strict2.md +++ b/docs/camellia-id-gen/strict2.md @@ -15,7 +15,8 @@ * seq取13位的情况下(最大8192/秒),用到52位(js的最大精度),可以使用17432年 * 相比CamelliaStrictIdGen的风险点在于,如果redis中的key丢失了(主从切换或者驱逐等),可能导致id在短时间内(1s内)产生重复或者回溯 -### 用法(直接使用) +### 用法 + 引入maven依赖 ``` diff --git a/docs/camellia-redis-proxy/other/camellia-redis-proxy-bootstrap.md b/docs/camellia-redis-proxy/other/camellia-redis-proxy-bootstrap.md index 206b83e65..ba5aa4f8b 100644 --- a/docs/camellia-redis-proxy/other/camellia-redis-proxy-bootstrap.md +++ b/docs/camellia-redis-proxy/other/camellia-redis-proxy-bootstrap.md @@ -8,7 +8,7 @@ * nacos管理配置文件,使用: `mvn clean package -Pnacos-config` * 使用zookeeper作为注册中心,使用: `mvn clean package -Pzk-register` * 使用hbase模拟redis协议,使用: `mvn clean package -Pkv-hbase` -* 使用obkv的hbase-client模拟redis协议,使用: `mvn clean package -Pkv-obkv` +* 使用obkv模拟redis协议,使用: `mvn clean package -Pkv-obkv` * 使用tikv模拟redis协议,使用: `mvn clean package -Pkv-tikv` ### 1、安装java(jdk21+) @@ -28,7 +28,7 @@ cd /yourdict/redis-proxy jar xvf camellia-redis-proxy-bootstrap-xxx.jar rm -rf camellia-redis-proxy-bootstrap-xxx.jar touch start.sh -echo "java -XX:+UseG1GC -Xms4096m -Xmx4096m -server org.springframework.boot.loader.JarLauncher" > start.sh +echo "java -XX:+UseG1GC -Dio.netty.tryReflectionSetAccessible=true --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/jdk.internal.access=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/sun.net.util=ALL-UNNAMED -Xms4096m -Xmx4096m -server org.springframework.boot.loader.JarLauncher" > start.sh chmod +x start.sh cd .. tar zcvf redis-proxy.tar.gz ./redis-proxy