[TOC]
# 簡介
Consul是HashiCorp公司推出的開源工具,用于實現分布式系統的服務發現與配置。 Consul是分布式的、高可用 的、可橫向擴展的。它具備以下特性 :
service discovery:consul通過DNS或者HTTP接口使服務注冊和服務發現變的很容易,一些外部服務,例如saas 提供的也可以一樣注冊。
health checking:健康檢測使consul可以快速的告警在集群中的操作。和服務發現的集成,可以防止服務轉發到 故障的服務上面。
key/value storage:一個用來存儲動態配置的系統。提供簡單的HTTP接口,可以在任何地方操作。 multi-datacenter:無需復雜的配置,即可支持任意數量的區域
# 安裝
安裝包僅包含一個可執行文件。 Consul安裝非常簡單,只需要下載對應系統的軟件包并解壓后就可使用。
~~~
# 這里以 Linux系統為例:
$ wget https://releases.hashicorp.com/consul/1.2.0/consul_1.2.0_linux_amd64.zip
$ unzip consul_1.2.0_linux_amd64.zip
$ mv consul /usr/local/bin/
~~~
安裝 Consul后,通過執行 consul命令,你可以看到命令列表的輸出
~~~
consul
~~~
## Consul 的角色
* client: 客戶端, 無狀態, 將 HTTP 和 DNS 接口請求轉發給局域網內的服務端集群.
* server: 服務端, 保存配置信息, 高可用集群, 在局域網內與本地客戶端通訊, 通過廣域網與其他數據中心通訊. 每個數據中心的 server 數量推薦為 3 個或是 5 個.
## 運行 Consul代理
Consul是典型的 C/S架構,可以運行服務模式或客戶模式。每一個數據中心必須有至少一個服務節點, 3到5個服 務節點最好。非常不建議只運行一個服務節點,因為在節點失效的情況下數據有極大的丟失風險。
## 運行Agent
完成Consul的安裝后,必須運行agent. agent可以運行為server或client模式.每個數據中心至少必須擁有一臺server. 建議在一個集群中有3或者5個server.部署單一的server,在出現失敗時會不可避免的造成數據丟失. 其他的agent運行為client模式.一個client是一個非常輕量級的進程.用于注冊服務,運行健康檢查和轉發對server的查詢.agent必須在集群中的每個主機上運行.
## 啟動 Consul Server
~~~
#node1:
$ consul agent -server -bootstrap-expect 2 -data-dir /tmp/consul -node=n1 -bind=192.168.110.123 -ui -config-dir /etc/consul.d -rejoin -join 192.168.110.123 -client 0.0.0.0
#運行cosnul agent以server模式
-server : 定義agent運行在server模式
-bootstrap-expect :在一個datacenter中期望提供的server節點數目,當該值提供的時候,consul一直 等到達到指定sever數目的時候才會引導整個集群,該標記不能和bootstrap共用 -data-dir:提供一個目錄用來存放agent的狀態,所有的agent允許都需要該目錄,該目錄必須是穩定的,系統 重啟后都繼續存在
-node:節點在集群中的名稱,在一個集群中必須是唯一的,默認是該節點的主機名 -bind:該地址用來在集群內部的通訊,集群內的所有節點到地址都必須是可達的,默認是0.0.0.0
-ui: 啟動web界面
-config-dir::配置文件目錄,里面所有以.json結尾的文件都會被加載 -rejoin:使consul忽略先前的離開,在再次啟動后仍舊嘗試加入集群中。 -client:consul服務偵聽地址,這個地址提供HTTP、DNS、RPC等服務,默認是127.0.0.1所以不對外提供服 務,如果你要對外提供服務改成0.0.0.0
#node2:
$ consul agent -server -bootstrap-expect 2 -data-dir /tmp/consul -node=n2 -
bind=192.168.110.148 -ui -rejoin -join 192.168.110.123
-server : 定義agent運行在server模式
-bootstrap-expect :在一個datacenter中期望提供的server節點數目,當該值提供的時候,consul一直 等到達到指定sever數目的時候才會引導整個集群,該標記不能和bootstrap共用 -bind:該地址用來在集群內部的通訊,集群內的所有節點到地址都必須是可達的,默認是0.0.0.0 -node:節點在集群中的名稱,在一個集群中必須是唯一的,默認是該節點的主機名
-ui: 啟動web界面
-rejoin:使consul忽略先前的離開,在再次啟動后仍舊嘗試加入集群中。 -config-dir::配置文件目錄,里面所有以.json結尾的文件都會被加載 -client:consul服務偵聽地址,這個地址提供HTTP、DNS、RPC等服務,默認是127.0.0.1所以不對外提供服 務,如果你要對外提供服務改成0.0.0.0
-join 192.168.110.121 : 啟動時加入這個集群
~~~
## 啟動consul client
~~~
#node3:
$ consul agent -data-dir /tmp/consul -node=n3 -bind=192.168.110.124 -config-dir /etc/consul.d -rejoin -join 192.168.110.123
運行cosnul agent以client模式,-join 加入到已有的集群中去。
~~~
## 查看集群成員
新開一個終端窗口運行consul members, 你可以看到Consul集群的成員.

## 停止Agent
你可以使用Ctrl-C 優雅的關閉Agent. 中斷Agent之后你可以看到他離開了集群并關閉.
在退出中,Consul提醒其他集群成員,這個節點離開了.如果你強行殺掉進程.集群的其他成員應該能檢測到這個節點失 效了.當一個成員離開,他的服務和檢測也會從目錄中移除.當一個成員失效了,他的健康狀況被簡單的標記為危險,但 是不會從目錄中移除.Consul會自動嘗試對失效的節點進行重連.允許他從某些網絡條件下恢復過來.離開的節點則不 會再繼續聯系.
此外,如果一個agent作為一個服務器,一個優雅的離開是很重要的,可以避免引起潛在的可用性故障影響達成一致性 協議. consul優雅的退出
~~~
consul leave
~~~
## web頁面
~~~
http://127.0.0.1:8500/ui
~~~
## 注冊服務
搭建好conusl集群后,用戶或者程序就能到consul中去查詢或者注冊服務。可以通過提供服務定義文件或者調用HTTP API來注冊一個服務. 首先,為Consul配置創建一個目錄.Consul會載入配置文件夾里的所有配置文件.在Unix系統中通常類似`/etc/consul.d` (.d 后綴意思是這個路徑包含了一組配置文件).
~~~
mkdir /etc/consul.d
~~~

**測試程序**
~~~
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Println("hello Web3! This is n3或者n2")
fmt.Fprintf(w, "Hello Web3! This is n3或者n2") }
func healthHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("health check! n3或者n2")
}
func main() {
http.HandleFunc("/", handler)
http.HandleFunc("/health", healthHandler)
http.ListenAndServe(":10000", nil)
}
~~~
**查詢服務**
一旦agent啟動并且服務同步了.我們可以通過DNS或者HTTP的API來查詢服務.
**DNS API**
讓我們首先使用DNS API來查詢.在DNS API中,服務的DNS名字是 NAME.service.consul. 雖然是可配置的,但默認的 所有DNS名字會都在consul命名空間下.這個子域告訴Consul,我們在查詢服務,NAME則是服務的名稱.
對于我們上面注冊的Web服務.它的域名是 web.service.consul :
~~~
dig @127.0.0.1 -p 8600 web.service.consul
~~~
有也可用使用 DNS API 來接收包含 地址和端口的 SRV記錄:
~~~
dig @127.0.0.1 -p 8600 web.service.consul SRV
~~~
# 基本命令介紹
~~~
agent 指令是consul的核心,它運行agent來維護成員的重要信息、運行檢查、服務宣布、查詢處理等等。
event 命令提供了一種機制,用來fire自定義的用戶事件,這些事件對consul來說是不透明的,
但它們可以用來構建自動部署、重啟服務或者其他行動的腳本。
exec 指令提供了一種遠程執行機制,比如你要在所有的機器上執行uptime命令,
遠程執行的工作通過job來指定,存儲在KV中,agent使用event系統可以快速的知道有新的job產生,
消息是通過gossip協議來傳遞的,因此消息傳遞是最佳的,但是并不保證命令的執行。
事件通過gossip來驅動,遠程執行依賴KV存儲系統(就像消息代理一樣)。
force-leave 治療可以強制consul集群中的成員進入left狀態(空閑狀態),記住,即使一個成員處于活躍狀態,
它仍舊可以再次加入集群中,這個方法的真實目的是強制移除failed的節點。如果failed的節點還是網絡的一部分,
則consul會周期性的重新鏈接failed的節點,如果經過一段時間后(默認是72小時),
consul則會宣布停止嘗試鏈接failed的節點。force-leave指令可以快速的把failed節點轉換到left狀態。
info 指令提供了各種操作時可以用到的debug信息,對于client和server,info有返回不同的子系統信息,
目前有以下幾個KV信息:agent(提供agent信息),consul(提供consul庫的信息),raft(提供raft庫的信息),
serf_lan(提供LAN gossip pool),serf_wan(提供WAN gossip pool)
join 指令告訴consul agent加入一個已經存在的集群中,一個新的consul agent必須加入一個已經有至少一個成員的集群中,
這樣它才能加入已經存在的集群中,如果你不加入一個已經存在的集群,則agent是它自身集群的一部分,
其他agent則可以加入進來。agents可以加入其他agent多次。consul join [options] address。
如果你想加入多個集群,則可以寫多個地址,consul會加入所有的地址。
keygen 指令生成加密的密鑰,可以用在consul agent通訊加密
leave 指令觸發一個優雅的離開動作并關閉agent,節點離開后不會嘗試重新加入集群中。
運行在server狀態的節點,節點會被優雅的刪除,這是很嚴重的,
在某些情況下一個不優雅的離開會影響到集群的可用性。
members 指令輸出consul agent目前所知道的所有的成員以及它們的狀態,
節點的狀態只有alive、left、failed三種狀態。
monitor 指令用來鏈接運行的agent,并顯示日志。monitor會顯示最近的日志,
并持續的顯示日志流,不會自動退出,除非你手動或者遠程agent自己退出。
reload 指令可以重新加載agent的配置文件。SIGHUP指令在重新加載配置文件時使用,
任何重新加載的錯誤都會寫在agent的log文件中,并不會打印到屏幕。
version 打印consul的版本
watch 指令提供了一個機制,用來監視實際數據視圖的改變(節點列表、成員服務、KV),
如果沒有指定進程,當前值會被dump出來
ui web ui界面的命令
~~~
# consul架構

client不持久化數據
我們只看數據中心1,可以看出consul的集群是由N個SERVER,加上M個CLIENT組成的。
而不管是SERVER還是 CLIENT,都是consul的一個節點,所有的服務都可以注冊到這些節點上,正是通過這些節點實現服務注冊信息的 共享。
除了這兩個,還有一些小細節,一一簡單介紹。
CLIENT CLIENT表示consul的client模式,就是客戶端模 式。
是consul節點的一種模式,這種模式下,所有注冊到當前節點的服務會被轉發到SERVER【通過HTTP和DNS接 口請求server】,本身是不持久化這些信息。 SERVER SERVER表示consul的server模式,表明這個consul是個 server,這種模式下,功能和CLIENT都一樣,唯一不同的是,它會把所有的信息持久化的本地,這樣遇到故障,信 息是可以被保留的 SERVER-LEADER 中間那個SERVER下面有LEADER的字眼,表明這個SERVER是它們的老大, 它和其它SERVER不一樣的一點是,它需要負責同步注冊的信息給其它的SERVER,同時也要負責各個節點的健康監 測。
**Consul的client mode把請求轉向server,那么client的作用是什么?**
consul可以用來實現分布式系統的服務發現與配置。client把服務請求傳遞給server,server負責提供服務以及和 其他數據中心交互。題主的問題是,既然server端提供了所有服務,那為何還需要多此一舉地用client端來接收一 次服務請求。我想,采用這種架構有以下幾種理由: 首先server端的網絡連接資源有限。對于一個分布式系統, 一般情況下訪問量是很大的。如果用戶能不通過client直接地訪問數據中心,那么數據中心必然要為每個用戶提供
~~~
$ dig @127.0.0.1 -p 8600 web.service.consul SRV
~~~
一個單獨的連接資源(線程,端口號等等),那么server端的負擔會非常大。
所以很有必要用大量的client端來分散用 戶的連接請求,在client端先統一整合用戶的服務請求,然后一次性地通過一個單一的鏈接發送大量的請求給 server端,能夠大量減少server端的網絡負擔。
其次,在client端可以對用戶的請求進行一些處理來提高服務的效 率,比如將相同的請求合并成同一個查詢,再比如將之前的查詢通過cookie的形式緩存下來。
但是這些功能都需要 消耗不少的計算和存儲資源。
如果在server端提供這些功能,必然加重server端的負擔,使得server端更加不穩 定。
而通過client端來進行這些服務就沒有這些問題了,因為client端不提供實際服務,有很充足的計算資源來進行 這些處理這些工作。 最后還有一點,consul規定只要接入一個client就能將自己注冊到一個服務網絡當中。這種架 構使得系統的可擴展性非常的強,網絡的拓撲變化可以特別的靈活。這也是依賴于client—server結構的。如果系 統中只有幾個數據中心存在,那網絡的擴張也無從談起了。
- 基礎
- 簡介
- 主要特征
- 變量和常量
- 編碼轉換
- 數組
- byte與rune
- big
- sort接口
- 和mysql類型對應
- 函數
- 閉包
- 工作區
- 復合類型
- 指針
- 切片
- map
- 結構體
- sync.Map
- 隨機數
- 面向對象
- 匿名組合
- 方法
- 接口
- 權限
- 類型查詢
- 異常處理
- error
- panic
- recover
- 自定義錯誤
- 字符串處理
- 正則表達式
- json
- 文件操作
- os
- 文件讀寫
- 目錄
- bufio
- ioutil
- gob
- 棧幀的內存布局
- shell
- 時間處理
- time詳情
- time使用
- new和make的區別
- container
- list
- heap
- ring
- 測試
- 單元測試
- Mock依賴
- delve
- 命令
- TestMain
- path和filepath包
- log日志
- 反射
- 詳解
- plugin包
- 信號
- goto
- 協程
- 簡介
- 創建
- 協程退出
- runtime
- channel
- select
- 死鎖
- 互斥鎖
- 讀寫鎖
- 條件變量
- 嵌套
- 計算單個協程占用內存
- 執行規則
- 原子操作
- WaitGroup
- 定時器
- 對象池
- sync.once
- 網絡編程
- 分層模型
- socket
- tcp
- udp
- 服務端
- 客戶端
- 并發服務器
- Http
- 簡介
- http服務器
- http客戶端
- 爬蟲
- 平滑重啟
- context
- httptest
- 優雅中止
- web服務平滑重啟
- beego
- 安裝
- 路由器
- orm
- 單表增刪改查
- 多級表
- orm使用
- 高級查詢
- 關系查詢
- SQL查詢
- 元數據二次定義
- 控制器
- 參數解析
- 過濾器
- 數據輸出
- 表單數據驗證
- 錯誤處理
- 日志
- 模塊
- cache
- task
- 調試模塊
- config
- 部署
- 一些包
- gjson
- goredis
- collection
- sjson
- redigo
- aliyunoss
- 密碼
- 對稱加密
- 非對稱加密
- 單向散列函數
- 消息認證
- 數字簽名
- mysql優化
- 常見錯誤
- go run的錯誤
- 新手常見錯誤
- 中級錯誤
- 高級錯誤
- 常用工具
- 協程-泄露
- go env
- gometalinter代碼檢查
- go build
- go clean
- go test
- 包管理器
- go mod
- gopm
- go fmt
- pprof
- 提高編譯
- go get
- 代理
- 其他的知識
- go內存對齊
- 細節總結
- nginx路由匹配
- 一些博客
- redis為什么快
- cpu高速緩存
- 常用命令
- Go 永久阻塞的方法
- 常用技巧
- 密碼加密解密
- for 循環迭代變量
- 備注
- 垃圾回收
- 協程和纖程
- tar-gz
- 紅包算法
- 解決golang.org/x 下載失敗
- 逃逸分析
- docker
- 鏡像
- 容器
- 數據卷
- 網絡管理
- 網絡模式
- dockerfile
- docker-composer
- 微服務
- protoBuf
- GRPC
- tls
- consul
- micro
- crontab
- shell調用
- gorhill/cronexpr
- raft
- go操作etcd
- mongodb