「原創宣告:保留所有權利,禁止轉載」
前文分享 etcd 框架 Go 語言的實踐,今天分享一下 Java 客戶端的不分。再分享之前,先簡單聊一下我查閱的資料的現狀,以方便各位再開始 Java 客戶端學習之前,有個心理預期。
etcd 本身是 Go 語言編寫的,所以在語言支援上,Go 語言是支援的最好的。其他的就差強人意,這種場景有點像 Web3j
,有人再維護,但是從使用便捷程度上,總是不能一帆風順直接上手。
而且還有一個原因,etcd 的 Java 實現庫太多了,各種庫之間的細微差異也能讓我搜尋資料的時候難以準確找到最佳實踐及其原理介紹。
大多數實現庫都用了大量的非同步操作,語法跟 Web3j
類似,我也不確定是哪種設計模式,如果你有 Web3j
使用經驗,相信會更加容易上手。
Java 客戶端比較
特性 | jetcd | etcd4j | spring-cloud-kubernetes | vertx-etcd-client |
---|---|---|---|---|
維護者 | etcd-io (CoreOS) | jurmous | Spring Cloud | Eclipse Vert.x |
etcd 相容性 | v3 API | 主要支援 v2 API | v3 API | v3 API |
非同步支援 | 是 | 是 | 是 | 是 |
依賴 | gRPC | Netty | Spring Cloud | Vert.x |
特點 | 官方支援,全面的功能 | 輕量級,簡單易用 | 與 Spring Cloud 整合 | 與 Vert.x 生態系統整合 |
適用場景 | 大型專案,需要全面功能 | 簡單使用,遺留系統 | Spring Cloud 專案 | Vert.x 專案 |
Watch 支援 | 是 | 是 | 是 | 是 |
事務支援 | 是 | 有限 | 透過 Spring 抽象 | 是 |
效能 | 高 | 中等 | 依賴 Spring 抽象 | 高 |
社群活躍度 | 高 | 低 | 高 | 中等 |
文件質量 | 詳細 | 一般 | 詳細 | 詳細 |
學習曲線 | 中等 | 低 | 高(如果不熟悉 Spring) | 中等 |
詳細比較
-
jetcd
- 優點:
- 官方支援,與 etcd 版本同步更新
- 全面支援 etcd v3 API
- 效能優秀,適合大規模生產環境
- 缺點:
- 依賴較重(gRPC)
- 學習曲線可能稍陡
- 優點:
-
etcd4j
- 優點:
- 輕量級,容易整合
- API 簡單直觀
- 缺點:
- 主要支援 etcd v2 API,對 v3 支援有限
- 社群更新較慢
- 不適合需要 v3 API 特性的新專案
- 優點:
-
spring-cloud-kubernetes
- 優點:
- 與 Spring Cloud 和 Kubernetes 生態系統深度整合
- 提供服務發現和配置管理功能
- 缺點:
- 依賴 Spring 生態系統,不適合非 Spring 專案
- 可能引入不必要的複雜性(如果只需要簡單的 etcd 客戶端)
- 優點:
-
vertx-etcd-client
- 優點:
- 與 Vert.x 生態系統整合
- 非阻塞 API,適合高併發場景
- 缺點:
- 與 Vert.x 繫結,不適合非 Vert.x 專案
- 社群相對較小
- 優點:
Java 客戶端實踐
下面我選擇 jetcd
作為實現庫,首先我們新增依賴專案:
<dependency>
<groupId>io.etcd</groupId>
<artifactId>jetcd-core</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
如果你再執行當中遇到了 Exception in thread "main" java.lang.NoClassDefFoundError:
此類錯誤,請檢查服務端版本,gRPC 版本,客戶端版本,以及依賴項缺失。這也是勸退的原因之一。
接下來我們來看 Case,除了讀寫以外,我增加了監聽的用例。總體來講,語法比較熟悉(我用過 Web3j
),下面是兩個簡單的例子,用來演示 jetcd
的基本使用。
package com.funtest.temp
import com.funtester.frame.SourceCode
import io.etcd.jetcd.ByteSequence
import io.etcd.jetcd.Client
import io.etcd.jetcd.Watch
import io.etcd.jetcd.kv.GetResponse
import io.etcd.jetcd.watch.WatchEvent
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import java.util.concurrent.CompletableFuture
class TtcdTest extends SourceCode {
static Charset defaultCharset = StandardCharsets.UTF_8
// 建立客戶端, 連線etcd
static def client = Client.builder().endpoints("http://localhost:2379").build()
// 建立KV客戶端, 用於讀寫資料
static def kVClient = client.getKVClient()
static def watchClient = client.getWatchClient()
/**
* 監聽etcd中的key變化, 有變化時列印出來
*/
static watch() {
def key = toByteSequence("key")// 監聽的key
Watch.Listener listener = Watch.listener(watchResponse -> {// 監聽器
for (WatchEvent event : watchResponse.getEvents()) {// 事件
println("watch change ------------------")// 列印
println("修改的型別Event type: " + event.getEventType());// 事件型別, PUT, DELETE
println("修改的Key: " + event.getKeyValue().getKey().toString(StandardCharsets.UTF_8));// 修改的Key, ByteSequence轉字串
println("修改後Value: " + event.getKeyValue().getValue().toString(StandardCharsets.UTF_8));// 修改後的Value, ByteSequence轉字串
}
});
watchClient.watch(key, listener)// 監聽key, 有變化時觸發監聽器
}
/**
* 寫入資料, 讀取資料
* @return
*/
static writeRead() {
kVClient.put(toByteSequence("key"), toByteSequence("FunTester")).get()// 寫入key-value
CompletableFuture<GetResponse> getFuture = kVClient.get(toByteSequence("key"))// 讀取key-value
GetResponse response = getFuture.get()// 獲取結果, 阻塞等待, 直到獲取到結果
println("Value: " + response.getKvs().get(0).getValue().toString())// 列印結果
}
/**
* 字串轉ByteSequence
* @param str
* @param Charset
* @return
*/
static ByteSequence toByteSequence(String str, Charset = defaultCharset) {
return ByteSequence.from(str, defaultCharset);
}
}
下面我們來依次執行兩個方法:
public static void main(String[] args) {
watch()
writeRead()
}
下面是控制檯列印:
watch change ------------------
修改的型別Event type: PUT
修改的Key: key
修改後Value: FunTester
Value: FunTester
可以看到是滿足預期的。但是問題來了,JVM 程序就是不退出,比較尷尬,即使我們加上關閉客戶端的方法 client.close()
也不行,開啟執行緒轉儲之後發現好幾個 RUNNABLE
的執行緒,還有一個 forkjoin
執行緒池,現象跟 Web3j
很像,但是這次跟 Netty
相關,我也懶得深究原因了。
- 2021 年原創合集
- 2022 年原創合集
- 2023 年原創合集
- 服務端功能測試
- 效能測試專題
- Java、Groovy、Go、Python
- 單元&白盒&工具合集
- 測試方案&BUG&爬蟲&UI 自動化
- 測試理論雞湯
- 社群風采&影片合集
如果覺得我的文章對您有用,請隨意打賞。您的支援將鼓勵我繼續創作!
打賞支援
暫無回覆。