1. 程式人生 > >Consul 踩坑日記,節點id衝突

Consul 踩坑日記,節點id衝突

簡介

之前公司用的是Consul進行服務發現以及服務管理,自己一直以來只是用一下,但是沒有具體的深入,覺得學習不可以這樣,所以稍微研究了一下。

網上有很多關於Consul的介紹和對比,我這裡也不獻醜了,大家搜尋的時候可能會經常看到這麼一個表格,此表格採摘自:https://luyiisme.github.io/2017/04/22/spring-cloud-service-discovery-products/

Feature Consul zookeeper etcd euerka
服務健康檢查 服務狀態,記憶體,硬碟等 (弱)長連線,keepalive 連線心跳 可配支援
多資料中心 支援
kv儲存服務 支援 支援 支援
一致性 raft paxos raft
cap ca cp cp ap
使用介面(多語言能力) 支援http和dns 客戶端 http/grpc http(sidecar)
watch支援 全量/支援long polling 支援 支援 long polling 支援 long polling/大部分增量
自身監控 metrics metrics metrics
安全 acl /https acl https支援(弱)
spring cloud整合 已支援 已支援 已支援 已支援

下載並配置Consul

我這裡是直接使用的虛擬機器進行配置Consul,系統是CentOS 7,Consul的安裝和配置其實網上也是有一堆教程,這裡簡單的介紹一下,Consul的下載地址(https://www.consul.io/downloads.html),根據需要選擇不同的包:

下載Consul的ZIP包以及使用unzip進行解壓,這裡簡單貼幾個命令:

$ wget https://releases.hashicorp.com/consul/1.2.0/consul_1.2.0_linux_amd64.zip
$ yum install unzip
$ unzip consul_0.7.2_linux_amd64.zip
$ mv consul /usr/local/bin/consul

到此,就可以在控制檯中輸入consul,然後看到有如下列印結果,即代表正常:

開始配置,consul預設有如下幾種Mode:

  1. dev ,快捷配置,一般用於除錯模式
  2. server,伺服器
  3. client,客戶端

學習Consul的時候,會有很多教程可能為了快速的入門,所以在配置Consul的時候,直接使用了dev模式,我個人覺得使用這個模式沒什麼意思,因為使用這個dev效果就跟單機模式是一樣的,我們這裡是學習分散式架構的,所以不採用。

剩下的還有server模式以及client模式,server模式好理解,在我們搭建的叢集中,都是使用此模式。可是client模式主要是用來做什麼呢?先看一眼下面的圖片:

(圖片摘自:https://andyyoung01.github.io/2016/09/27/%E4%BD%BF%E7%94%A8Consul%E8%BF%9B%E8%A1%8C%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0/)

上面的圖片大致的意思就是有一個server叢集,然後如果我們的服務想要加入server叢集,就必須要通過client來進行rpc呼叫。(這個是我的理解,大家可以進行補充)

大致理解了這麼一個結構之後,我們開始進行叢集的配置,我這裡通過虛擬機器進行模擬,有如下幾臺機器:

  1. 192.168.32.133     server1(叢集伺服器)
  2. 192.168.32.134    server2(叢集伺服器)
  3. 192.168.32.135    server3(叢集伺服器)

三個做叢集伺服器,還有一個是客戶端,叢集伺服器是由一個CentOS的虛擬機器以及其兩個拷貝組成,客戶端我是在我的筆記本上裝了一個Ubuntu的作業系統來實現的。

大致結構瞭解了之後,我們開始進行配置:

叢集伺服器的配置分別為:

$ consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=server1 -client=0.0.0.0 -bind=192.168.32.133
$ consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=server2 -client=0.0.0.0 -bind=192.168.32.134
$ consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=server3 -client=0.0.0.0 -bind=192.168.32.135

簡單說一下幾個配置:

  • agent                      Consul的核心命令,主要作用有維護成員資訊、執行狀態檢測、宣告服務以及處理請求等
  • -server                    就是代表server模式
  • -ui                           代表開啟web 控制檯
  • -bootstrap-expect        代表想要建立的叢集數目,官方建議3或者5
  • -data-dir                       資料儲存目錄
  • -node                           代表當前node的名稱
  • -client                          應該是一個客戶端服務註冊的地址,可以和當前server的一致也可以是其他主機地址,系統預設是127.0.0.1
  • -bind                            叢集通訊地址

上述命令執行完成之後,開始將這些分散的伺服器組成叢集,命令如下,分別在192.168.125.121和192.168.125.120機器上執行:

$ consul join 168.168.125.118

這裡我執行了這個命令之後,得到報錯資訊,資訊大致如下:

Failed to join 192.168.125.118:dial tcp 192.168.125.118:8301:connect:no route to host(這裡大致文字描述一下,方便搜尋)

 查詢了一下,之所以出現這個情況是因為CentOS的防火牆,將8301埠加入防火牆就好了,命令大致如下:

$ firewall-cmd --zone=public --add-port=8301/tcp --permanent
$ firewall-cmd --reload    /*必須新增,否則重啟之後會失效*/

再次執行加入叢集命令,出現以下問題:

consul: Failed to confirm peer status for server2: rpc error getting client: failed to get conn: dial tcp 192.168.125.120:0->192.168.125.121:8300: connect: no route to host. Retrying in 1s...

產生這個的原因和上面的一致,加入叢集需要和8300埠進行通訊,所以再次將8300埠加入防火牆,這裡再說一下,再把8500埠也加入防火牆,因為這個埠是web控制檯使用的。

再次執行加入叢集命令,再次報錯,因為是虛擬機器,而且我是克隆的,後面發現在執行這些命令之後,會有如下提示:

* Failed to join 192.168.125.118: Member 'server1' has conflicting node ID 'b76ff298-accd-05ff-8c64-5d79d866dfa9' with this agent's ID

通過查詢,網上給出的兩個解決辦法分別如下:

一是在啟動agent的時候加入-disable-host-node-id引數,禁止生成node-id。類似這樣:

$ consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=server1 -client=0.0.0.0 -bind=192.168.125.118 -disable-host-node-id

二是可以用-node-id生成一個新的node-id,類似這樣:

$ consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=server1 -client=0.0.0.0 -bind=192.168.125.118 -node-id=$(uuidgen | awk '{print tolower($0)}')

上面兩種方法我都試過,但是都不好使,應該是因為這個node-id已經存在於資料儲存目錄(即/tmp/consul),名字就叫node-id,使用vi或者vim開啟之後可以看到一個guid格式的資訊,這裡儲存的就是node ID的資訊,無奈,我只能刪除這個檔案,然後重新啟動命令,得到正常的反饋資訊。