- 原文地址:Java and etcd: together at last, with jetcd
- 原文做者:Fanmin Shi
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:mingxing
- 校對者:xiantang
可靠的鍵值存儲爲分佈式系統提供了一致性配置和協調的公共基礎。etcd 項目就是一個這樣的系統,這是一個由 CoreOS 建立的開源鍵值存儲系統。它是許多生產級分佈式系統的核心組件和 Kubernetes 等項目的數據存儲中心。html
Java 已經經過在包括 Hadoop 生態系統、Cassandra 數據存儲和雲基礎設施技術棧中的使用而證實了本身是一種流行的分佈式系統語言。此外,它仍然是一種很是流行的語言。能夠看看在谷歌趨勢的統計數據中,Java 仍然佔據主導地位: 前端
就谷歌搜索結果而言,Java 仍然比 Microsoft 的 .Net 甚至 JavaScript 語言更受歡迎java
面對着 Java 的流行及其在分佈式系統中的廣泛使用,咱們認爲對於 Java 開發來講,etcd 也應該做爲後端基礎被使用到。jetcd 這個新的 etcd 客戶端的出現,將 etcd v3 API 帶到了 Java 中。android
經過使用 jetcd,Java 應用程序可使用包裝了 etcd 的原生 gRPC 協議的智能 API 來與 etcd 進行純粹的交互。該 API 提供了僅在 etcd 上可用的表達性分佈式特性。更重要的是,經過直接支持更多的語言,使用新的使用模式更容易爲 etcd 編寫新的應用程序,從而幫助 etcd 變得更加穩定和可靠。ios
你能夠經過構建並運行一個名爲 jetcdctl
的小例子程序來試用 jetcd,該程序使用了 jetcd 去訪問 etcd。對於更進一步的 jetcd 項目來講,jetcdctl 示例也是一個很好的起點。要繼續學習,你還須要同時安裝 Git 和 Java。git
首先,克隆 jetcd 庫來獲取 jetcd 源碼,而後使用 Maven 來構建 jetcd-simple-ctl
吧:github
$ git clone https://github.com/coreos/jetcd.git
$ cd jetcd/jetcd-examples/jetcd-simple-ctl
$ ./mvnw clean package
複製代碼
構建並準備好運行 jetcdctl
以後,下載一個 etcd 發行版並在本地啓動一個 etcd 服務。(譯者注:若如下 「go get」 命令沒法正常運行,能夠參考這裏的資料):apache
# build with 「go get github.com/coreos/etcd/cmd/etcd」
$ etcd &
複製代碼
接下來,使用 jetcdctl
將 123
寫入 abc
,與本地 etcd 服務器進行通訊:後端
$ java -jar target/jetcdctl.jar put abc 123
21:39:06.126|INFO |CommandPut - OK
複製代碼
你能夠經過讀取 abc
來確認寫入 etcd 的 put 命令的正確性:api
$ java -jar target/jetcdctl.jar get abc 21:41:00.265|INFO |CommandGet - abc 21:41:00.267|INFO |CommandGet - 123
複製代碼
咱們已經經過 get 和 put keys 演示了 jetcd 的基本功能。如今,讓咱們進一步研究如何在代碼中使用 jetcd 吧。
jetcd API 能夠方便地管理 etcd 的底層 gRPC 協議。一個例子是 streaming key 事件,其中客戶端觀察 key,etcd 服務端不斷地往客戶端發回更新信息。jetcd 客戶端管理着一個低級別的 gRPC 流,用來優雅地處理斷開鏈接,並向用戶呈現一個無縫的事件流。
若是 jetcd 應用程序但願接收到一個 key 的全部更新,它將使用 watch API 來建立一個 Watcher:
Watcher watch(ByteSequence key) 複製代碼
Watcher
的 listen
方法從 etcd 中讀取 WatchResponse
消息。每一個 WatchResponse
包含被監視 key 上的最新事件序列。若是沒有任何事件,則 listen
被阻塞,直到有更新爲止。listen
方法是可靠的;它不會在調用之間刪除任何事件,即便在斷開鏈接的狀況下:
WatchResponse listen() throws InterruptedException 複製代碼
總之,客戶端建立一個 Watcher
,而後使用 listen
來等待事件。下面是在 key abc
上進行觀察的代碼,打印觀察到的 key 和 value,直到 listen
拋出異常:總之,客戶端建立一個 Watcher
,而後使用 listen
來等待事件。下面是觀察 key abc
的代碼,打印 key 和 value,直到 listen
拋出異常:
Client client = Client.builder().endpoints(「http://127.0.0.1:2379).build();
Watcher watcher = client.getWatchClient().watch(ByteSequence.fromString("abc"));
while (true) {
for (WatchEvent event : watcher.listen().getEvents()) {
KeyValue kv = event.getKeyValue();
System.out.println(event.getEventType());
System.out.println(kv.getKey().toStringUtf8());
System.out.println(kv.getValue().toStringUtf8());
}
}
複製代碼
將此特性與 Apache 基金會中與 etcd 對標的 ZooKeeper 進行比較。從 ZooKeeper 3.4.10 開始,watch 就已是一次性觸發器,這意味着一旦收到一個 watch 事件,您必須設置一個新的 watch,以便在未來發生更改時獲得通知。要傳輸密鑰事件,可會斷必須與集羣聯繫,爲每一個新事件註冊一個新的觀察者。
要在 key 更新時連續打印 key 的內容,ZooKeeper 應用程序首先建立一個 Watcher 來偵聽 WatchedEvent
消息。觀察程序實現了一個事件回調方法 process
,當 key 發生更改時就會調用該方法。要在事件中註冊興趣,觀察程序須要添加到 exists 方法中,該方法獲取 key 的元數據(若是有的話)。當 key 發生變化時,觀察者的 process
方法就會調用 getData 來檢索 key 的值,而後再次註冊相同的觀察者來接收將來的更改,以下所示:
key = 「/abc」;
Watcher w = new Watcher() {
public void process(WatchedEvent event) {
try {
System.out.println(event.getType());
System.out.println(event.getPath());
if (event.getType() != EventType.NodeDeleted) {
System.out.println(new String(zk.getData(event.getPath(), false, null)));
}
zk.exists(key, this);
} catch (Exception e) {
e.printStackTrace();
}
}
};
zk.exists(key, w);
複製代碼
與 jetcd 示例不一樣,ZooKeeper 代碼不能保證它觀察全部更改,由於在監視程序接收事件和發送請求以獲取新監視之間存在延遲。例如,在執行 process
和調用 exists
以註冊新監視程序之間發生了一個事件。因爲沒有註冊任何觀察程序,所以該事件永遠不會被觸發,而且會丟失。
即便假設全部事件都已觸發,代碼仍然可能破壞事件流。沒有 etcd 提供的多版本併發控制,就沒法訪問歷史 key。若是 key value 在接收事件和獲取數據之間發生了變化,代碼將打印出最新的值,而不是與 watch 事件關聯的值。更糟的是,事件沒有附帶修訂信息;沒法肯定 key 是來自事件仍是來自 future 返回。
從 v0.0.1 開始,jetcd 支持大多數應用程序須要的鍵值存儲。這些原語能夠做爲複雜模式(如分佈式隊列、barriers 等)的構建塊。在將來,jetcd 將可以使用 etcd 的本地鎖和領導人選舉 rpc 進行集羣範圍的標準化分佈式協調。
jetcd 設計目的是易於使用,同時還可以利用 etcd 的先進功能。它是開源的,而且正在活躍開發中,歡迎社區的貢獻和反饋。咱們能夠在 GitHub 上找到它,地址是github.com/coreos/jetc…。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。