目錄
- 一、簡介
- 二、maven依賴
- 三、配置
- 3.1、屬性組態檔
- 3.2、屬性配置類
- 3.3、zookeeper配置類(核心)
- 四、具體使用
- 4.1、zookeeperClient(核心)
- 4.2、controller層
- 五、測驗
- 5.1、多實體
- 5.2、nginx轉發配置
- 5.3、使用jmeter并發測驗
- 5.4、測驗結果
一、簡介
??zookeeper是一個分布式的,開放原始碼的分布式應用程式協調服務,它是一個為分布式應用提供一致性服務的軟體,提供的功能包括:配置維護、域名服務、分布式同步、組服務等,選擇zookeeper的原因,因為zookeeper具有以下優點:
- 可靠性:如果訊息被到一臺服務器接受,那么它將被所有的服務器接受,
- 實時性:在一定事件范圍內,client能讀到最新資料,如果需要最新資料,應該在讀資料之前呼叫sync()介面
- 獨立性:各個Client之間互不干預
- 順序性:更新請求順序進行,來自同一個client的更新請求按其發送順序依次執行
- 原子性:一次資料的更新只能成功或者失敗,沒有其他中間狀態
- 最終一致性:全域唯一資料視圖,client無論連接到哪個server,資料視圖都是一致的
二、maven依賴
??我這里把里面的日志框架都過濾了,加入了lombok,你們可以根據自己的需要進行相應的處理,
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/>
</parent>
<groupId>com.alian</groupId>
<artifactId>zookeeper-id</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zookeeper-id</name>
<description>Spring Boot之zookeeper唯一id</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 本例中你不加入容器也可以運行-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.14</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
三、配置
3.1、屬性組態檔
??我們在resource目錄下建一個config檔案夾,然后在resource/config目錄下創建zookeeper的自定義組態檔zookeeper.properties,主要是zookeeper連接和目錄相關的配置,因為本機的配置原因,我這里就沒有采用zookeeper的集群模式了,Zookeeper建議集群節點個數為奇數(大于等于3),只要超過一半的機器能夠正常提供服務,那么整個集群都是可用的狀態,
zookeeper.properties
# zookeeper服務器地址(ip+port)
zookeeper.server=10.130.3.16:2181
# 節點創建的路徑約定用"/"結尾
zookeeper.rootPath=/root/alian/
# 休眠時間
zookeeper.sleep-time=1000
# 最大重試次數
zookeeper.max-retries=3
# 會話超時時間
zookeeper.session-timeout=5000
# 連接超時時間
zookeeper.connection-timeout=5000
3.2、屬性配置類
??此配置類不懂的可以參考我另一篇文章:Spring Boot讀取組態檔常用方式
ZookeeperProperties.java
package com.alian.zookeeperid.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "zookeeper")
//讀取指定路徑組態檔,暫不支持*.yaml檔案
@PropertySource(value = "classpath:config/zookeeper.properties", encoding = "UTF-8", ignoreResourceNotFound = true)
public class ZookeeperProperties {
/**
* zookeeper服務地址
*/
private String server;
/**
* 根路徑
*/
private String rootPath;
/**
* 重試等待時間
*/
private int sleepTime;
/**
* 最大重試次數
*/
private int maxRetries;
/**
* session超時時間
*/
private int sessionTimeout;
/**
* 連接超時時間
*/
private int connectionTimeout;
}
3.3、zookeeper配置類(核心)
??為什么要使用Curator,因為Curator提供了簡化使用zookeeper更高級的API介面,CuratorFramework實體都是執行緒安全的,它包涵很多優秀的特性:
- 自動連接管理:自動處理zookeeper的連接和重試存在一些潛在的問題,可以監控節點資料改變和獲取更新服務的串列,而監控又可以自動被Cruator recipes洗掉
- 更簡潔的API:提供現代流式API介面,簡化了原生zookeeper方法,事件等
- Recipe實作:可以應用到leader選舉,分布式鎖,path快取,和watcher,分布式佇列等
ZookeeperConfig.java
package com.alian.zookeeperid.config;
import com.alian.zookeeperid.common.ZookeeperClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Slf4j
@Configuration
public class ZookeeperConfig {
@Autowired
private ZookeeperProperties zookeeperProperties;
@Bean
public CuratorFramework curatorFrameworkClient() {
//重試策略,ExponentialBackoffRetry(1000,3)這里表示等待1s重試,最大重試次數為3次
RetryPolicy policy = new ExponentialBackoffRetry(zookeeperProperties.getSleepTime(), zookeeperProperties.getMaxRetries());
//構建CuratorFramework實體
CuratorFramework curatorFrameworkClient = CuratorFrameworkFactory
.builder()
.connectString(zookeeperProperties.getServer())
.sessionTimeoutMs(zookeeperProperties.getSessionTimeout())
.connectionTimeoutMs(zookeeperProperties.getConnectionTimeout())
.retryPolicy(policy)
.build();
//啟動實體
curatorFrameworkClient.start();
return curatorFrameworkClient;
}
//采用這種方式可以比較優雅的關閉連接
@Bean(initMethod = "init", destroyMethod = "destroy")
public ZookeeperClient zookeeperClient(ZookeeperProperties zookeeperProperties, CuratorFramework curatorFrameworkClient) {
return new ZookeeperClient(zookeeperProperties, curatorFrameworkClient);
}
}
四、具體使用
4.1、zookeeperClient(核心)
??此組件主要是完成,順序節點的創建,我這里創建的是臨時順利節點,如果擔心節點過多可以采用異步執行緒洗掉節點,我這里也只是一個示例,我想我代碼的注釋比這個慘白的文字要更有說服力,很多小伙伴可能會采用@Component注解,我使用@Bean(initMethod = “init”, destroyMethod = “destroy”)來創建,可以比較優雅的關閉連接,當然在使用上是一樣的,只要不是同時對一個bean這么操作,
zookeeperClient.java
package com.alian.zookeeperid.common;
import com.alian.zookeeperid.config.ZookeeperProperties;
import com.sun.istack.internal.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
public class ZookeeperClient {
private ZookeeperProperties zookeeperProperties;
private static ExecutorService executorService;
private CuratorFramework curatorFramework;
public CuratorFramework getCuratorFramework() {
return curatorFramework;
}
public ZookeeperClient(ZookeeperProperties zookeeperProperties, CuratorFramework curatorFramework) {
this.zookeeperProperties = zookeeperProperties;
this.curatorFramework = curatorFramework;
}
public void init() {
log.info("ZookeeperClient初始化方法,新建執行緒池,用于洗掉臨時節點");
try {
//執行緒池用于洗掉異步洗掉節點
executorService = Executors.newFixedThreadPool(10);
} catch (Exception e) {
log.error("ZookeeperClient init error {}", e.getMessage());
}
}
public void destroy() {
try {
log.info("ZookeeperClient銷毀方法,如果zookeeper連接不為空,則關閉連接");
if (getCuratorFramework() != null) {
//這種方式比較優雅的關閉連接
getCuratorFramework().close();
}
} catch (Exception e) {
log.error("stop zookeeper client error {}", e.getMessage());
}
}
/**
* 分布式ID生成
*/
public String generateId(String nodeName) {
//創建臨時自動編號的順序節點,回傳的是一個路徑
String nodeFullPath = createSeqNode(nodeName);
if (null == nodeFullPath) {
return "";
}
String generateId = splitSeqNode(nodeFullPath);
log.info("節點編號:" + generateId);
return generateId;
}
/**
* 創建順序節點,約定nodePrefix不能為空,也不能用"/"開頭或結尾
*/
private String createSeqNode(@NotNull String nodePrefix) {
if ("".equals(nodePrefix.trim()) || nodePrefix.startsWith("/") || nodePrefix.endsWith("/")) {
log.error("節點前綴錯誤");
return "";
}
String nodeFullPath = "";
//根路徑+要創建節點的名稱(可以是路徑,此處傳入的nodeName不要用"/"開頭或結尾)
String fullPath = zookeeperProperties.getRootPath().concat(nodePrefix);
try {
//關鍵點:創建臨時順序節點
//creatingParentsIfNeeded():如果傳入的是路徑,并且節點父路徑不存在則創建父節點
nodeFullPath = curatorFramework
.create()
.creatingParentsIfNeeded()
.withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
.forPath(fullPath);
//為防止生成的節點浪費系統資源,故生成后異步洗掉此節點
cleanNode(nodeFullPath);
} catch (Exception e) {
log.error("創建臨時順序節點例外{}", e.getMessage());
e.printStackTrace();
}
return nodeFullPath;
}
private void cleanNode(String finalBackNodePath) {
executorService.execute(() -> {
try {
//Thread.sleep(10);
Stat stat = curatorFramework.checkExists().forPath(finalBackNodePath);
if (stat != null) {
// log.info("------------" + new String(curatorFramework.getData().forPath("/zookeeper/alian")));
curatorFramework.delete().forPath(finalBackNodePath);
// log.info("洗掉的臨時節點:{}", finalBackNodePath);
}
} catch (Exception e) {
log.error("洗掉節點例外{}", e.getMessage());
e.printStackTrace();
}
});
}
private String splitSeqNode(String path) {
//獲取最后一個"/"的索引,用于字串截取
int index = path.lastIndexOf("/");
if (index >= 0) {
//如果"/"位置比路徑長度小,則截取"/"后面的作為節點回傳
//如果"/"位置等于路徑長度,說明它后面沒有元素,回傳空字串
return index <= path.length() ? path.substring(index + 1) : "";
}
//不含"/",說明是節點資料,直接回傳(理論上不會,因為都是"/"開頭的路徑,至少有一個"/")
return path;
}
}
關于zookeeper里節點的模式,新版又增加了兩個帶TTL的持久化節點,節點模式:
- PERSISTENT:持久化節點
- PERSISTENT_SEQUENTIAL:持久化的順序自動編號節點
- EPHEMERAL:臨時節點
- EPHEMERAL_SEQUENTIAL:臨時順序自動編號節點
- CONTAINER:容器節點
- PERSISTENT_WITH_TTL:帶TTL(time-to-live,存活時間)的持久化節點,節點在TTL時間之內沒有得到更新并且沒有子節點,就會被自動洗掉
- PERSISTENT_SEQUENTIAL_WITH_TTL:帶TTL(time-to-live,存活時間)和單調遞增序號的持久節點,節點在TTL時間之內沒有得到更新并且沒有子節點,就會被自動洗掉
??可能很多小伙伴不知道怎么創建待TTL的節點,我也給大家準備了,主要是使用withTtl(5000L)設定過期
String fullPath="/root/alian/";
String nodePath = curatorFramework
.create()
.withTtl(5000L)
.creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT_SEQUENTIAL_WITH_TTL)
.forPath(fullPath);
4.2、controller層
??簡單的一個獲取id的介面,僅僅是為了演示,實際中肯定更加嚴格和規范,生成時間字串yyyyMMddHHmmssSSS+zookeeper生產的id,組成我們需要的id,當然你也可以使用其他的前綴,
DistributedIdController.java
package com.alian.zookeeperid.controller;
import com.alian.zookeeperid.common.ZookeeperClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
@RestController
@RequestMapping("/distributed")
public class DistributedIdController {
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
@Autowired
private ZookeeperClient zookeeperClient;
/**
* 生成id
*
* @return
*/
@RequestMapping("/generateId")
public String generateId(HttpServletRequest request) {
//我們這里傳入前綴為時間字串:yyyyMMddHHmmssSSS
String nodeName = LocalDateTime.now().format(formatter);
return zookeeperClient.generateId(nodeName);
}
}
五、測驗
5.1、多實體
??由于我們是windows環境下的本機開發及測驗,我們使用idea啟動兩個實體進行負載均衡,埠分別為8088和8090,如果不懂的可以參考我另一篇文章:windows下Nginx配置及負載均衡使用
application.yml
server:
port: 8088
servlet:
context-path: /zookeeperId
兩個實體啟動的示例圖:

5.2、nginx轉發配置
??自定義組態檔localhost_80.conf里server模塊里增加轉發配置,通過負載均衡到兩個實體上,
location ~ ^/zookeeperId/ {
proxy_redirect off;
#埠
proxy_set_header Host $host;
#遠程地址
proxy_set_header X-Real-IP $remote_addr;
#程式可獲取遠程ip地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#此處會用的upstream.conf,此檔案在nginx.conf已經引入了
proxy_pass http://zookeeper-id;
}
負載均衡配置upstream.conf檔案增加下面的配置,其中zookeeper-id 就是localhost_80.conf檔案里配置的http://zookeeper-id;
upstream zookeeper-id {
server 127.0.0.1:8088 ;
server 127.0.0.1:8090 ;
}
如果你的nginx已經啟動,最后記得使用命令nginx -t 檢查和nginx -s reload應用,
5.3、使用jmeter并發測驗
??本文中使用使用100個執行緒請求我的介面獲取id,100表示執行緒數,0表示0秒內一起發送,1表示請求回圈的次數,

我們請求的地址是:http://localhost/zookeeperId/distributed/generateId,注意是沒有埠的,會通過nginx轉發到后臺實體,

5.4、測驗結果
埠為8088實體的結果:
2021-10-20 15:25:51 347 [http-nio-8088-exec-21] INFO generateId 39:節點編號:202110201525512590000000001
2021-10-20 15:25:51 347 [http-nio-8088-exec-7] INFO generateId 39:節點編號:202110201525512600000000003
2021-10-20 15:25:51 347 [http-nio-8088-exec-31] INFO generateId 39:節點編號:202110201525512590000000005
2021-10-20 15:25:51 348 [http-nio-8088-exec-23] INFO generateId 39:節點編號:202110201525512590000000007
2021-10-20 15:25:51 349 [http-nio-8088-exec-30] INFO generateId 39:節點編號:202110201525512600000000009
2021-10-20 15:25:51 350 [http-nio-8088-exec-10] INFO generateId 39:節點編號:202110201525512600000000012
2021-10-20 15:25:51 350 [http-nio-8088-exec-14] INFO generateId 39:節點編號:202110201525512590000000014
2021-10-20 15:25:51 351 [http-nio-8088-exec-29] INFO generateId 39:節點編號:202110201525512590000000017
2021-10-20 15:25:51 352 [http-nio-8088-exec-5] INFO generateId 39:節點編號:202110201525512600000000019
2021-10-20 15:25:51 352 [http-nio-8088-exec-8] INFO generateId 39:節點編號:202110201525512600000000022
2021-10-20 15:25:51 352 [http-nio-8088-exec-38] INFO generateId 39:節點編號:202110201525512590000000020
2021-10-20 15:25:51 353 [http-nio-8088-exec-15] INFO generateId 39:節點編號:202110201525512590000000028
2021-10-20 15:25:51 353 [http-nio-8088-exec-48] INFO generateId 39:節點編號:202110201525512600000000024
2021-10-20 15:25:51 354 [http-nio-8088-exec-35] INFO generateId 39:節點編號:202110201525512590000000027
2021-10-20 15:25:51 354 [http-nio-8088-exec-18] INFO generateId 39:節點編號:202110201525512600000000029
2021-10-20 15:25:51 354 [http-nio-8088-exec-26] INFO generateId 39:節點編號:202110201525512590000000032
2021-10-20 15:25:51 355 [http-nio-8088-exec-45] INFO generateId 39:節點編號:202110201525512600000000035
2021-10-20 15:25:51 355 [http-nio-8088-exec-22] INFO generateId 39:節點編號:202110201525512590000000036
2021-10-20 15:25:51 356 [http-nio-8088-exec-12] INFO generateId 39:節點編號:202110201525512590000000038
2021-10-20 15:25:51 356 [http-nio-8088-exec-41] INFO generateId 39:節點編號:202110201525512600000000040
2021-10-20 15:25:51 357 [http-nio-8088-exec-49] INFO generateId 39:節點編號:202110201525512590000000043
2021-10-20 15:25:51 357 [http-nio-8088-exec-50] INFO generateId 39:節點編號:202110201525512600000000044
2021-10-20 15:25:51 358 [http-nio-8088-exec-34] INFO generateId 39:節點編號:202110201525512600000000046
2021-10-20 15:25:51 358 [http-nio-8088-exec-11] INFO generateId 39:節點編號:202110201525512590000000048
2021-10-20 15:25:51 359 [http-nio-8088-exec-42] INFO generateId 39:節點編號:202110201525512600000000052
2021-10-20 15:25:51 359 [http-nio-8088-exec-9] INFO generateId 39:節點編號:202110201525512590000000050
2021-10-20 15:25:51 359 [http-nio-8088-exec-19] INFO generateId 39:節點編號:202110201525512590000000055
2021-10-20 15:25:51 360 [http-nio-8088-exec-17] INFO generateId 39:節點編號:202110201525512590000000057
2021-10-20 15:25:51 361 [http-nio-8088-exec-1] INFO generateId 39:節點編號:202110201525512600000000059
2021-10-20 15:25:51 361 [http-nio-8088-exec-25] INFO generateId 39:節點編號:202110201525512600000000061
2021-10-20 15:25:51 362 [http-nio-8088-exec-16] INFO generateId 39:節點編號:202110201525512600000000065
2021-10-20 15:25:51 362 [http-nio-8088-exec-43] INFO generateId 39:節點編號:202110201525512600000000067
2021-10-20 15:25:51 362 [http-nio-8088-exec-6] INFO generateId 39:節點編號:202110201525512600000000062
2021-10-20 15:25:51 364 [http-nio-8088-exec-39] INFO generateId 39:節點編號:202110201525512590000000069
2021-10-20 15:25:51 364 [http-nio-8088-exec-4] INFO generateId 39:節點編號:202110201525512600000000073
2021-10-20 15:25:51 366 [http-nio-8088-exec-40] INFO generateId 39:節點編號:202110201525512590000000075
2021-10-20 15:25:51 366 [http-nio-8088-exec-32] INFO generateId 39:節點編號:202110201525512600000000081
2021-10-20 15:25:51 366 [http-nio-8088-exec-33] INFO generateId 39:節點編號:202110201525512590000000079
2021-10-20 15:25:51 367 [http-nio-8088-exec-27] INFO generateId 39:節點編號:202110201525512600000000085
2021-10-20 15:25:51 367 [http-nio-8088-exec-46] INFO generateId 39:節點編號:202110201525512600000000087
2021-10-20 15:25:51 368 [http-nio-8088-exec-44] INFO generateId 39:節點編號:202110201525512600000000098
2021-10-20 15:25:51 367 [http-nio-8088-exec-47] INFO generateId 39:節點編號:202110201525512590000000089
2021-10-20 15:25:51 367 [http-nio-8088-exec-28] INFO generateId 39:節點編號:202110201525512590000000091
2021-10-20 15:25:51 367 [http-nio-8088-exec-20] INFO generateId 39:節點編號:202110201525512600000000097
2021-10-20 15:25:51 367 [http-nio-8088-exec-13] INFO generateId 39:節點編號:202110201525512600000000077
2021-10-20 15:25:51 368 [http-nio-8088-exec-2] INFO generateId 39:節點編號:202110201525512600000000099
2021-10-20 15:25:51 367 [http-nio-8088-exec-37] INFO generateId 39:節點編號:202110201525512590000000084
2021-10-20 15:25:51 367 [http-nio-8088-exec-36] INFO generateId 39:節點編號:202110201525512600000000092
2021-10-20 15:25:51 367 [http-nio-8088-exec-3] INFO generateId 39:節點編號:202110201525512590000000095
2021-10-20 15:25:51 367 [http-nio-8088-exec-24] INFO generateId 39:節點編號:202110201525512600000000071
埠為8090實體的結果:
2021-10-20 15:25:51 347 [http-nio-8090-exec-18] INFO generateId 39:節點編號:202110201525512570000000000
2021-10-20 15:25:51 347 [http-nio-8090-exec-30] INFO generateId 39:節點編號:202110201525512560000000002
2021-10-20 15:25:51 347 [http-nio-8090-exec-12] INFO generateId 39:節點編號:202110201525512550000000004
2021-10-20 15:25:51 349 [http-nio-8090-exec-34] INFO generateId 39:節點編號:202110201525512560000000010
2021-10-20 15:25:51 348 [http-nio-8090-exec-27] INFO generateId 39:節點編號:202110201525512560000000006
2021-10-20 15:25:51 349 [http-nio-8090-exec-24] INFO generateId 39:節點編號:202110201525512560000000008
2021-10-20 15:25:51 349 [http-nio-8090-exec-14] INFO generateId 39:節點編號:202110201525512560000000011
2021-10-20 15:25:51 349 [http-nio-8090-exec-40] INFO generateId 39:節點編號:202110201525512560000000013
2021-10-20 15:25:51 350 [http-nio-8090-exec-1] INFO generateId 39:節點編號:202110201525512560000000015
2021-10-20 15:25:51 350 [http-nio-8090-exec-13] INFO generateId 39:節點編號:202110201525512550000000016
2021-10-20 15:25:51 351 [http-nio-8090-exec-6] INFO generateId 39:節點編號:202110201525512560000000018
2021-10-20 15:25:51 352 [http-nio-8090-exec-39] INFO generateId 39:節點編號:202110201525512560000000021
2021-10-20 15:25:51 353 [http-nio-8090-exec-17] INFO generateId 39:節點編號:202110201525512560000000023
2021-10-20 15:25:51 353 [http-nio-8090-exec-5] INFO generateId 39:節點編號:202110201525512560000000025
2021-10-20 15:25:51 353 [http-nio-8090-exec-4] INFO generateId 39:節點編號:202110201525512550000000026
2021-10-20 15:25:51 354 [http-nio-8090-exec-11] INFO generateId 39:節點編號:202110201525512550000000031
2021-10-20 15:25:51 354 [http-nio-8090-exec-33] INFO generateId 39:節點編號:202110201525512560000000030
2021-10-20 15:25:51 354 [http-nio-8090-exec-23] INFO generateId 39:節點編號:202110201525512560000000033
2021-10-20 15:25:51 354 [http-nio-8090-exec-26] INFO generateId 39:節點編號:202110201525512560000000034
2021-10-20 15:25:51 355 [http-nio-8090-exec-49] INFO generateId 39:節點編號:202110201525512550000000037
2021-10-20 15:25:51 356 [http-nio-8090-exec-2] INFO generateId 39:節點編號:202110201525512560000000039
2021-10-20 15:25:51 356 [http-nio-8090-exec-35] INFO generateId 39:節點編號:202110201525512550000000041
2021-10-20 15:25:51 357 [http-nio-8090-exec-19] INFO generateId 39:節點編號:202110201525512560000000042
2021-10-20 15:25:51 357 [http-nio-8090-exec-50] INFO generateId 39:節點編號:202110201525512560000000045
2021-10-20 15:25:51 358 [http-nio-8090-exec-3] INFO generateId 39:節點編號:202110201525512560000000047
2021-10-20 15:25:51 359 [http-nio-8090-exec-43] INFO generateId 39:節點編號:202110201525512560000000049
2021-10-20 15:25:51 359 [http-nio-8090-exec-47] INFO generateId 39:節點編號:202110201525512560000000051
2021-10-20 15:25:51 359 [http-nio-8090-exec-25] INFO generateId 39:節點編號:202110201525512560000000053
2021-10-20 15:25:51 359 [http-nio-8090-exec-48] INFO generateId 39:節點編號:202110201525512560000000054
2021-10-20 15:25:51 360 [http-nio-8090-exec-10] INFO generateId 39:節點編號:202110201525512560000000056
2021-10-20 15:25:51 361 [http-nio-8090-exec-15] INFO generateId 39:節點編號:202110201525512560000000060
2021-10-20 15:25:51 361 [http-nio-8090-exec-9] INFO generateId 39:節點編號:202110201525512560000000058
2021-10-20 15:25:51 362 [http-nio-8090-exec-31] INFO generateId 39:節點編號:202110201525512560000000064
2021-10-20 15:25:51 363 [http-nio-8090-exec-29] INFO generateId 39:節點編號:202110201525512550000000063
2021-10-20 15:25:51 363 [http-nio-8090-exec-36] INFO generateId 39:節點編號:202110201525512560000000066
2021-10-20 15:25:51 364 [http-nio-8090-exec-37] INFO generateId 39:節點編號:202110201525512560000000070
2021-10-20 15:25:51 362 [http-nio-8090-exec-22] INFO generateId 39:節點編號:202110201525512560000000068
2021-10-20 15:25:51 364 [http-nio-8090-exec-20] INFO generateId 39:節點編號:202110201525512570000000072
2021-10-20 15:25:51 364 [http-nio-8090-exec-42] INFO generateId 39:節點編號:202110201525512560000000074
2021-10-20 15:25:51 364 [http-nio-8090-exec-28] INFO generateId 39:節點編號:202110201525512550000000076
2021-10-20 15:25:51 365 [http-nio-8090-exec-44] INFO generateId 39:節點編號:202110201525512570000000080
2021-10-20 15:25:51 365 [http-nio-8090-exec-32] INFO generateId 39:節點編號:202110201525512560000000083
2021-10-20 15:25:51 365 [http-nio-8090-exec-21] INFO generateId 39:節點編號:202110201525512560000000078
2021-10-20 15:25:51 365 [http-nio-8090-exec-46] INFO generateId 39:節點編號:202110201525512550000000082
2021-10-20 15:25:51 365 [http-nio-8090-exec-8] INFO generateId 39:節點編號:202110201525512560000000086
2021-10-20 15:25:51 366 [http-nio-8090-exec-45] INFO generateId 39:節點編號:202110201525512560000000088
2021-10-20 15:25:51 366 [http-nio-8090-exec-16] INFO generateId 39:節點編號:202110201525512560000000090
2021-10-20 15:25:51 367 [http-nio-8090-exec-38] INFO generateId 39:節點編號:202110201525512560000000093
2021-10-20 15:25:51 368 [http-nio-8090-exec-7] INFO generateId 39:節點編號:202110201525512560000000094
2021-10-20 15:25:51 368 [http-nio-8090-exec-41] INFO generateId 39:節點編號:202110201525512560000000096
??從上述結果來看,每次生成的id確實是不一樣的,生成的節點為10位從0000000000開始編號,每個執行緒列印的順序可能會有先后,最后生成的節點還是從0000000000~0000000099,00000000099在8088埠實體里輸出了,本例里是倒數第5個,
??需要提醒的是本文中zookeeper服務的版本是3.6.3,curator-framework的版本是5.2.0,如果你的zookeeper服務版本是3.4.x,可能就會出現問題,
org.apache.zookeeper.ClientCnxn$SessionTimeoutException: Client session timed out, have not heard from server in 10106ms for session id 0x0
這時你就需要去更改你依賴里的版本為3.4.x,同時需要注意的是你的curator-framework版本也要改成,你可以多嘗試幾次,我一般喜歡使用新的版本,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/337645.html
標籤:其他
上一篇:2021年秋招總結
