您好,登錄后才能下訂單哦!
本篇內容介紹了“如何使用四字命令與Admin Server”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
> JMX(Java Management Extensions,即 Java 管理擴展)是一個為應用程序、設備、系統等植入管理功能的框架。JMX 可以跨越一系列異構操作系統平臺、系統體系結構和網絡傳輸協議,靈活的開發無縫集成的系統、網絡和服務管理應用。
是不是聽不懂?聽不懂就對了,如果你從來沒有開發過 JMX 或者應用過的話,我這里就簡單介紹下:JMX 就是 Java 提供的一個標準,這個標準可以將一些有需要的 Java 對象運行時的狀態暴露出去(這些對象可以叫 MBean),一般是用于監控或者運行時修改一些配置信息。
我們既然是講解 ZK,那么我現在就有問題了,現在我手里有一個簡單 ZK 集群正在運行,我想知道哪個節點是 Leader,怎么辦?
首先 ZK 本身在啟動的時候就會主動將一些對象注冊成為 MBean,而我們直接使用 Java 自帶的工具 jconsole
就能查看,下面我演示下,我這里有一個簡單的 ZK 集群:
$ jps 5266 QuorumPeerMain 2964 10438 Jps 4550 Launcher 5286 QuorumPeerMain 5767 JConsole 5388 QuorumPeerMain 9215 Launcher
可以看到有三個 QuorumPeerMain
的進程,就代表了這個集群的三個節點。
下面我們使用 jconsole
打開該工具(安裝了 jdk,這個工具就自動擁有了)
$ jconsole
圖中顯示操作的地方都是可以在右側找到一個按鈕進行調用的(還可以傳參),關于 ZK 中 JMX 更多的細節,我這里暫時不披露了,之后有機會單獨講解,反正大家只需要知道 JMX 就是將一些普通 Java 對象暴露出去,可以通過工具查看屬性或者調用該對象的方法的一個標準。
剛剛那個 JMX 查看還是比較麻煩的,因為現在我們測試訪問的是我本地的進程,如果是遠程的 JVM 進程,用 jconsole
訪問起來就更麻煩了,有沒有簡單一點的方法。肯定是有!ZK 本身支持了一些四字命令(4lw)用于和服務端進行交互。
我這里做一個簡單的演示,我本地的集群的客戶端端口分別是:2181、2182、2183,我通過 telnet
命令隨便連接上一個節點:
$ telnet localhost 2181 Trying ::1... Connected to localhost. Escape character is '^]'.
就會進入交互模式,然后輸入 srvr
按下回車,就能得到以下輸出
$ telnet localhost 2181 Trying ::1... Connected to localhost. Escape character is '^]'. srvr Zookeeper version: 3.6.2--803c7f1a12f85978cb049af5e4ef23bd8b688715, built on 09/04/2020 12:44 GMT Latency min/avg/max: 0/3.8261/44 Received: 30 Sent: 29 Connections: 1 Outstanding: 0 Zxid: 0x100000009 Mode: leader Node count: 6 Proposal sizes last/min/max: 48/48/94 Connection closed by foreign host.
srvr
命令就是用來查看服務節點的狀態的,從輸出中的 Mode
字段就能看到,監聽 2181 端口的這個節點就是 Leader,我們再換一個 2182 節點看看,Mode
就是 Follower。
$ telnet localhost 2182 Trying ::1... Connected to localhost. Escape character is '^]'. srvr Zookeeper version: 3.6.2--803c7f1a12f85978cb049af5e4ef23bd8b688715, built on 09/04/2020 12:44 GMT Latency min/avg/max: 0/0.0/0 Received: 3 Sent: 3 Connections: 1 Outstanding: 0 Zxid: 0x100000009 Mode: follower Node count: 6 Connection closed by foreign host.
這里要提一下默認的四字命令不是全部打開的,如果想要啟用所有的四字命令需要在環境變量中指定 zookeeper.4lw.commands.whitelist=*
,也可以通過列出具體的命令(逗號分隔)來啟用指定的一些四字命令。我們再換個命令看看吧,比如 envi
,就會輸出當前節點的環境參數
java.io.tmpdir=/var/folders/19/bx8xsqgd1c78g5j1mt_zq5v80000gp/T/ java.compiler=<na> os.name=Mac OS X os.arch=x86_64 os.version=10.16 user.name=junjiexun user.home=/Users/junjiexun user.dir=/Users/junjiexun/develop/zk os.memory.free=101MB os.memory.max=889MB os.memory.total=123MB
我這里列一下所有的四字命令的作用,具體就不演示了,留給讀者自己嘗試吧,官網四字命令列表,四字命令其實就是它右邊命令的別名而已,作用是完全一樣的。(* 依舊表示 TODO,之后開篇單講)
命令 | 返回數據的作用 |
---|---|
conf / configuration | 配置信息(常用的 dataDir 、clientPort 等) |
cons / connections | 連接信息 |
crst / connection_stat_reset | 重置連接統計信息 |
dump | 會話信息和臨時節點 |
envi / environment | 環境變量信息(os.name 、user.home 等) |
ruok | 服務是否正常 |
srst / stat_reset | 重置統計信息 |
srvr / server_stats | 服務端信息概覽 |
stat | 服務端信息統計 |
wchs / watch_summary | 回調 watcher 的匯總 |
wchc / watches | 注冊回調的 session 信息匯總 |
dirs | log 和 snap 文件字節大小 |
wchp / watches_by_path | 注冊回調的路徑信息 |
mntr / monitor | 所有監控信息 |
isro / is_read_only | 當前節點是否是只讀 |
hash | 數字摘要 |
gtmk / get_trace_mask* | 獲取跟蹤掩碼 |
stmk / set_trace_mask* | 設置跟蹤掩碼 |
lsnp / last_snapshot | 最后一次快照的信息 |
icfg / initial_configuration | 服務端啟動初始配置 |
orst / observer_connection_stat_reset | 重置 Observer 連接統計信息 |
obsr / observers | 獲取 Observer 的信息 |
sysp / system_properties | 環境變量信息和 envi 不同的是會返回 zookeeper 開頭的自定義配置 |
lead / leader | 當前節點是否是 Leader |
voting_view | 集群選票信息 |
zabstate | ZAB 狀態信息匯總 |
我還看到了 ruok
,用來查看服務器節點是否啟動(能成功返回不代表能對外提供服務 )
直接訪問這些超鏈接就可以擁有和之前四字命令一樣的效果~也可以直接在 URL 上訪問 ip:port/commands/<commandname>
。
以 mntr
為例,可以直接訪問 http://localhost:8080/commands/mntr
或者 http://localhost:8080/commands/monitor
都是一樣的。
在此之前,我先介紹下 ZK 支持的兩種計票規則。
這是 ZK 默認的計票規則,用于各種服務端集群需要 ACK 的場景,假設現在的配置是這樣:
server.1=zoo1:2888:3888:participant server.2=zoo2:2888:3888:participant server.3=zoo3:2888:3888:participant server.4=zoo4:2888:3888:observer server.5=zoo5:2888:3888:observer
因為 Observer 是不會算入選票的,實際參與的機器是前三個節點:1、2、3
先不管 Leader 是誰,默認的計票規則需要這三個節點中的至少兩個成功提交 ACK(或是其他需要計票的信息),這個選舉(或者提案)才能被繼續提交,這就是過半機制。
ZK 還提供了一個新的計票規則,這個規則支持將各個節點分成不同的組(當然也可以只有一個組),同一個組中的不同節點也可以被分配成不同的權重,我舉個例子:
group.1=1:2:3 group.2=4:5:6:7:8 group.3=9 weight.1=1 weight.2=1 weight.3=1 weight.4=1 weight.5=1 weight.6=1 weight.7=1 weight.8=1 weight.9=1
group 開頭和 weight 開頭分別對應了分組和權重的配置,規定如下:
group 的格式是 group.<groupid>=<serverid>:<serverid>...
weight 的格式是 weight.<serverid>=<weight>
serverId 就是每一個服務節點配置在 myid 中的數字
每一個節點只能屬于一個 group
那以我現在配置的情況繼續說明的話,現在一共有三個 group,分別的權重計算如下 :
group1 的權重總和 = server1 的權重 + server2 的權重 + server3 的權重 = 1 + 1 + 1 = 3 group2 的權重總和 = server4 的權重 + server5 的權重 + server6 的權重 + server7 的權重 + server8 的權重= 1 + 1 + 1 + 1 + 1 = 5 group3 的權重總和 = server9 的權重 = 1
假如現在成功 ACK 的服務節點有 1、4、5、8、9 并以這樣的配置進行計票的話
首先看 group1 只有 server1 成功回復 ACK,權重值為 1,并未超過 group1 權重總和 3 一半以上,所以 group1 相當于 ACK 失敗了
再看 group2 有 4、5、8 三個節點成功回復 ACK,權重值為 3,超過了 group2 權重總和 5 的一半以上(3 > 5/2),所以 group2 ACK 成功
然后看 group3,因為只有一個節點 9,并成功回復 ACK,所以也滿足了超過 group3 權重總和 1 的一半以上(1 > 1/2),所以 group3 ACK 成功
最后統計成功 ACK 的 group 數量是否超過整體 group 數量的一半以上,現在有 2 個 group 成功 ACK(2 > 3/2) ,所以最終 ACK 通過
感覺看起來和默認的過半機制差不多,No,No,No。我這里看起來差不多的原因是因為我把權重都設置成了 1,如果設置成別的數字呢?
剛剛的場景中只有 group1 的 ACK 最終失敗了,原因是因為只有 server1 一個節點成功回復,但是如果我把 group1 的權重改成(另外兩個 group 省略了)
group.1=1:2:3 weight.1=3 weight.2=1 weight.3=1
現在 group1 的權重總和變成了 3 + 1 + 1 = 5
,server1 的權重是 3 了,就算只有它一個節點回復了,也超過了 group1 的一半以上(3 > 5/2),如果是此時的權重配置的話,group1 也是算作成功 ACK 的。
還有必須要說明的一點,在 ZK 讀取這些配置的時候就會計算每一個 group 的權重總和,如果計算出來某一個 group 的權重總和是 0,則該 group 被移除出計票規則中了。
和默認的過半機制不同的是,使用權重配置的話,是可以讓 Observer 參與的。
說了半天,怎么啟用這個權重的計票規則呢?
(推薦)在 zoo.cfg
中配置 dynamicConfigFile
選項用來指定動態配置的路徑地址,將所有的 server 、group 和 weight 開頭的配置都移至該路徑的配置文件中。
將所有的 server 、group 和 weight 開頭的配置都直接配置在 zoo.cfg
文件中
只要在配置文件中被 ZK 發現有 group 或者 weight 開頭的配置,就表示啟用權重的計票規則,否則使用默認的過半機制。
我們之前的 server 前綴配置是這樣:
server.1=zoo1:2888:3888:participant
實際的 server 配置的格式應該是這樣的,可以將客戶端的端口配置在 server 配置中的(最后的分號后面)
server.1=zoo1:2888:3888:participant;2181
如果這樣配置的話,zoo.cfg
中就不需要配置 clientPort
選項了。
所以按照推薦的配置方式的話,zoo.cfg
就配置這些(路徑請根據讀者的電腦自行調整)
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/Users/junjiexun/develop/zk/zk01/data dynamicConfigFile=/Users/junjiexun/develop/zk/zk01/conf/zoo.dyn.cfg ...
而我在 /Users/junjiexun/develop/zk/zk01/conf/zoo.dyn.cfg
的文件中就可以配置
server.10000000000=127.0.0.1:2888:3888:participant;2181 server.2=127.0.0.1:2887:3887;2182 server.3=127.0.0.1:2886:3886;2183 group.1=10000000000:2:3 weight.10000000000=1 weight.2=1 weight.3=1
更詳細的可以查看官方文檔
那么問題來了,我這樣配置好了后,怎么才能動態的往集群中添加節點或者刪除節點呢?
Java 的客戶端提供了一個 getConfig
的方法
ZooKeeper client = new ZooKeeper("127.0.0.1:2181", 3000, null); byte[] config = client.getConfig(false, null); System.out.println(new String(config)); client.close();
打印出來的結果是
server.2=127.0.0.1:2887:3887:participant;0.0.0.0:2182 server.3=127.0.0.1:2886:3886:participant;0.0.0.0:2183 server.10000000000=127.0.0.1:2888:3888:participant;0.0.0.0:2181 group.1=2:3:10000000000 weight.2=1 weight.3=1 weight.10000000000=1 version=0
這些信息看起來和我們配置的 zoo.dyn.cfg
有點像但是又有點不一樣,不一樣的地方實際就是 ZK 幫我們自動補齊的格式,而這個返回的數據 ZK 是存在哪里的呢?ZK 在啟動的時候默認會在根路徑創建以下節點
/ |--zookeeper |--config |--quota
而 getConfig
返回的數據實際就是 /zookeeper/config
節點的數據,而且這個節點的權限只有 Read,不信你用 getData
試試,返回的數據是一樣的
ZooKeeper client = new ZooKeeper("127.0.0.1:2181", 3000, null); byte[] config = client.getData("/zookeeper/config", false, null); System.out.println(new String(config)); client.close();
現在可以獲取到這個配置了,那怎么去修改呢?ZK 官方提供了兩種方式:命令行、Java API。
如果使用 Java 內置的命令行工具,在支持的命令中就有一個 reconfig
命令,參數是:
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
另一種就是使用 Java 的客戶端代碼,我們之前一直使用的是 ZooKeeper
這個類,他還有一個子類叫 ZooKeeperAdmin
,這個子類就擁有 reconfigure
方法可以對配置進行修改,下面我來演示下,但在此之前我必須說明下動態修改配置的特性
動態修改配置分為:增量和非增量的方式
因為實際上修改的就是 /zookeeper/config
節點的數據,而這個節點默認只有 Read 權限,所以要么直接使用管理員權限進行修改操作,要么就在環境變量中配置 zookeeper.skipACL=yes
跳過 ACL 的校驗
使用增量方式修改配置的時候,集群的計票規則必須是過半機制!
使用非增量的方式修改配置時,兩種機制均可。
將 Follower 從集群配置中刪除,只是相當于把它降級為 Observer,它是仍然可以對外提供服務端,并且也同樣可以接受到 Leader 的消息
將 Leader 從集群配置中刪除時,會造成較大的性能影響,整個集群在選出新的 Leader 之前是無法對外提供服務的,請盡量不要這么做
而增加節點就輕松很多,新加入的節點會自動和 Leader 進行同步數據
假設我現在一共有 3 個節點,采用的是過半機制(必須得是),三個 ID 分別是 10000000000、2、3,我們嘗試將 ID 為 3 的節點刪除,我這里采用直接配置 skipACL
跳過權限校驗(下同)
ZooKeeperAdmin client = new ZooKeeperAdmin("127.0.0.1:2181", 3000, null); List<string> leavingServers = new ArrayList<>(); leavingServers.add("3"); byte[] reconfigure = client.reconfigure(null, leavingServers, null, -1, null); System.out.println(new String(reconfigure)); client.close();
該接口返回的數據就是 /zookeeper/config
修改完成后的配置信息,可以看到新的配置中和 3 有關的數據就消失了
server.2=127.0.0.1:2887:3887:participant;0.0.0.0:2182 server.10000000000=127.0.0.1:2888:3888:participant;0.0.0.0:2181 version=400000004
這個 version=400000004
是干嘛的呢?ZK 為修改的配置默認也提供了版本的控制,啟動成功后會在你配置的 dynamicConfigFile
路徑下自動生成一個文件,我這里是 zoo.cfg.dynamic.300000000
讀者可能跟我的不一樣。這個 300000000
就是版本號,而當我把 ID 為 3 的節點刪除后,ZK 又自動生成了個文件 zoo.cfg.dynamic.400000004
這個 400000004
就是新的版本號,如果我們在修改的時候對當前集群配置的版本號有要求的話就可以在 reconfigure
方法中的第四個參數填入需要的目標版本號即可,我例子中是 -1 代表無視版本號,和 delete、setData 的 version 字段是一個用意。
讓我們再把節點 3 加回去
ZooKeeperAdmin client = new ZooKeeperAdmin("127.0.0.1:2181", 3000, null); List<string> joiningServers = new ArrayList<>(); joiningServers.add("server.3=127.0.0.1:2886:3886;2183"); byte[] reconfigure = client.reconfigure(joiningServers, null, null, -1, null); System.out.println(new String(reconfigure)); client.close();
得到的新配置內容是
server.10000000000=127.0.0.1:2888:3888:participant;0.0.0.0:2181 server.2=127.0.0.1:2887:3887:participant;0.0.0.0:2182 server.3=127.0.0.1:2886:3886:participant;0.0.0.0:2183 version=400000013
節點 3 加回去了,而且版本號又改變了,又多了一個 zoo.cfg.dynamic.400000013
文件
ZooKeeperAdmin client = new ZooKeeperAdmin("127.0.0.1:2181", 3000, null); List<string> newMembers = new ArrayList<>(); newMembers.add("server.10000000000=127.0.0.1:2888:3888:participant;2181"); newMembers.add("server.3=127.0.0.1:2886:3886;2183"); byte[] reconfigure = client.reconfigure(null, null, newMembers, -1, null); System.out.println(new String(reconfigure)); client.close();
這樣的話相當于把 ID 為 2 的節點給刪除了(當然也可以新增節點,我這里就不演示了)
三種不同的方式實際對應的就是 Java API 的三個參數 joiningServers
、leavingServers
、newMembers
,而且 Java API 參數除了使用 List 還可以使用 String(逗號分隔)也可以達到同樣的效果。動態增刪服務節點讓我們可以在避免停機的前提下調整整個 ZK 集群的服務能力(個人覺得動態增加比較有用)。
而分組權重的計票規則提供了一種新的歸票策略,特別是配合動態配置,可以運行時修改權重,但總體來說,分組權重的計票規則比較雞肋,我也不知道能在什么樣的場景下使用(高性能的機器可以權重大一點?問題是現在都是云服務,容器化和虛擬化的,機器的配置都可以動態調整的,而且一般機器配置也都是一樣的,實在是想不到還有什么用)
如果讀者有關于分組權重的使用思路可以分享給大家噢~關于更多的動態配置可以參考 官方文檔
ZK 3.6 之后新增的 Metrics 是 ZK 提供給用戶可查詢的監控指標,官網上也說了可以結合 Prometheus 或者 Grafana 來使用。什么?你完全沒用過,甚至沒聽說過!那巧了這兩個東西我也沒玩過,借著這個機會就和大家一起學習下,搞個 Hello World,不過因為本系列是以 ZK 為主的,所以一切從簡配置,Let's GO!
Mac 安裝特別簡單,其他平臺可以去官網下載壓縮包
$ brew install prometheus
我這里的默認安裝路徑是 /usr/local/Cellar/prometheus/2.23.0
在此之前還需要在 ZK 節點的配置 zoo.cfg
加兩行
metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000
我是本地起的三個節點,另外兩個節點需要改成 7001 和 7002,因為端口不能重復
之后修改 Prometheus 的默認配置,在我的電腦上路徑為 /usr/local/etc/prometheus.yml
修改為
global: scrape_interval: 15s scrape_configs: - job_name: "test-zk" static_configs: - targets: ["localhost:7000", "localhost:7001", "localhost:7002"]
job_name 可以隨便起,重點是 targets 目標地址和 scrape_interval 訪問間隔,修改完畢后,就可以啟動 Prometheus
$ cd /usr/local/Cellar/prometheus/2.23.0 $ ./bin/prometheus --config.file=/usr/local/etc/prometheus.yml
然后訪問 localhost:9090
就能看到如下界面了:
只要勾上了 Enable autocomplete
就可以在輸入框里輸入了,馬上就能得到提示,我這里隨便輸幾個參數看看
簡單的就演示到這里了,剩下的交給讀者了~
Mac 安裝 Grafana 也非常簡單
$ brew install grafana
安裝完畢后,可以通過命令啟動
$ grafana-server --config=/usr/local/etc/grafana/grafana.ini --homepath /usr/local/share/grafana --packaging=brew cfg:default.paths.logs=/usr/local/var/log/grafana cfg:default.paths.data=/usr/local/var/lib/grafana cfg:default.paths.plugins=/usr/local/var/lib/grafana/plugins
Grafana 默認的端口是 3000,訪問 localhost:3000
默認的用戶名密碼均是 admin,就能看到首頁了
10465 這個數字哪兒來的呢?官方文檔的模板
大功告成!比 Prometheus 好看多了~
關于 ZK 的監控就介紹到這里了。傳統功夫,點到為止~
使用命令行操作 ZK 太麻煩了,所以可視化就很有必要了,下面推薦幾個不錯的可視化客戶端,有的是本地客戶端,有的是 Web 服務,大家按需獲取吧~
PrettyZoo:https://github.com/vran-dev/PrettyZoo ,可視化 GUI 客戶端,各個平臺都有安裝文件,需要連接 ZK 服務端的時候,手邊有這樣一個工具還是很方便的
zkdash:https://github.com/ireaderlab/zkdash ,JavaScript + Python 可視化 Web 客戶端,是個可以直接運行的 Web 服務,缺點是 Python2.7 開發的,如果不需要二次開發的話就沒什么問題
zoonavigator-web:https://github.com/elkozmon/zoonavigator-web ,TypeScript 編寫的可視化 Web 客戶端,是個可以直接運行的 Web 服務
visual-zookeeper:https://github.com/ghostg00/visual-zookeeper ,Electron + React 編寫的客戶端
“如何使用四字命令與Admin Server”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。