這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
本文的完整代碼見 https://github.com/changjixiong/goNotes/tree/master/consulnotes ,如果文中沒有顯示連結說明連結在被轉寄的時候被幹掉了,請搜尋找到原文閱讀。
consul是什麼
"Consul is a distributed, highly available, datacenter-aware, service discovery and configuration system. It can be used to present services and nodes in a flexible and powerful interface that allows clients to always have an up-to-date view of the infrastructure they are a part of."
引用一段網上對consul文檔的翻譯(http://consul.la/intro/what-is-consul)
Consul有多個組件,但是整體來看,它是你基礎設施中用於發現和佈建服務的一個工具。它提供如下幾個關鍵功能:* 服務發現: Consul的某些用戶端可以提供一個服務,例如api或者mysql,其它用戶端可以使用Consul去發現這個服務的提供者。使用DNS或者HTTP,應用可以很容易的找到他們所依賴的服務。* 健全狀態檢查: Consul用戶端可以提供一些健全狀態檢查,這些健全狀態檢查可以關聯到一個指定的服務(服務是否返回200 OK),也可以關聯到本地節點(記憶體使用量率是否在90%以下)。這些資訊可以被一個操作員用來監控叢集的健康狀態,被服務發現組件路由時用來遠離不健康的主機。* KVStore for Redis: 應用可以使用Consul提供的分層KVStore for Redis用於一些目的,包括動態配置、特徵標記、協作、leader選舉等等。通過一個簡單的HTTP API可以很容易的使用這個組件。* 多資料中心: Consul對多資料中心有非常好的支援,這意味著Consul使用者不必擔心由於建立更多抽象層而產生的多個地區。Consul被設計為對DevOps群體和應用開發人員友好,他非常適合現代的、可伸縮的基礎設施。
範例
網上關於consul的文檔及使用說明有很多,然而卻缺少關於使用的範例,接下來的內容將用一個範例來示範如何找到可服務的節點。完整的代碼見https://github.com/changjixiong/goNotes/tree/master/consulnotes
假設在一個系統中,節點A需要訪問某種服務,該服務有N個節點可提供服務,這些節點位於服務叢集groupB,節點A只需要串連上groupB中的任一節點即可獲得服務。
啟動consul
consul提供開發模式用於啟動單節點服務供開發調試用,運行命令consul agent -dev 啟動consul,輸出的資訊中有一行
Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)
顯示了consul運行參數,通過網址http://127.0.0.1:8500/ui/#/dc1/nodes可以查看節點與服務
註冊服務並添加健全狀態檢查
下面的代碼將向consul註冊一個服務
import ( "fmt" "log" "net/http" consulapi "github.com/hashicorp/consul/api")func consulCheck(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "consulCheck")}func registerServer() { config := consulapi.DefaultConfig() client, err := consulapi.NewClient(config) if err != nil { log.Fatal("consul client error : ", err) } checkPort := 8080 registration := new(consulapi.AgentServiceRegistration) registration.ID = "serverNode_1" registration.Name = "serverNode" registration.Port = 9527 registration.Tags = []string{"serverNode"} registration.Address = "127.0.0.1" registration.Check = &consulapi.AgentServiceCheck{ HTTP: fmt.Sprintf("http://%s:%d%s", registration.Address, checkPort, "/check"), Timeout: "3s", Interval: "5s", DeregisterCriticalServiceAfter: "30s", //check失敗後30秒刪除本服務 } err = client.Agent().ServiceRegister(registration) if err != nil { log.Fatal("register server error : ", err) } http.HandleFunc("/check", consulCheck) http.ListenAndServe(fmt.Sprintf(":%d", checkPort), nil)}
consulapi.DefaultConfig()的原始碼顯示預設採用的是http方式串連"127.0.0.1:8500",前文中顯示consul開發模式預設提供的http服務是在127.0.0.1:8500,在實際使用中需要設定為實際的參數。
consulapi.AgentServiceCheck中的HTTP指定了健全狀態檢查的介面地址即127.0.0.1:8080/check,consulCheck函數響應這個介面調用,返回200狀態代碼及一段字串"consulCheck",健全狀態檢查還有其他幾種方式,具體可以參考官方文檔。
consulapi.AgentServiceCheck中的DeregisterCriticalServiceAfter指定檢查不通過後多長時間登出本服務,這裡設定為30秒。
向consul註冊的服務地址為127.0.0.1:9527,以下是在127.0.0.1:9527上提供的echo服務。
ln, err := net.Listen("tcp", "0.0.0.0:9527") if nil != err { panic("Error: " + err.Error()) } for { conn, err := ln.Accept() if err != nil { panic("Error: " + err.Error()) } go EchoServer(conn) }
服務啟動後,訪問http://127.0.0.1:8500/ui/#/dc1/nodes 會發現 "2 services",點開後會在頁面上看到serverNode 127.0.0.1:9527,表明服務資訊已經註冊。以下資訊顯示健全狀態檢查通過。
HTTP GET http://127.0.0.1:8080/check: 200 OK Output: consulCheck
使用服務
服務使用方client通過以下代碼向consul查詢可用的服務(忽略錯誤處理)
client, err := consulapi.NewClient(consulapi.DefaultConfig())//非預設情況下需要設定實際的參數...services, err = client.Agent().Services()...if _, found := services["serverNode_1"]; !found { log.Println("serverNode_1 not found") continue} //尋找名為serverNode_1的服務
尋找到服務後串連服務並發送資料
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", service.Address, service.Port))...
client先啟動,服務後啟動,然後服務關閉,作業記錄如下:
serverNode_1 not foundget: EchoServerHello World, 001get: EchoServerHello World, 002...get: EchoServerHello World, 008Read Buffer Error: EOFdial tcp 127.0.0.1:9527: getsockopt: connection refuseddial tcp 127.0.0.1:9527: getsockopt: connection refused...dial tcp 127.0.0.1:9527: getsockopt: connection refusedserverNode_1 not foundserverNode_1 not found
服務啟動前提示serverNode_1沒找到,服務啟動後資料互動正常,服務關閉後consul尚未登出服務client提示服務無法串連,稍後consul登出了失效的服務,client顯示服務沒有找到。
使用情境設想
假設一個網路遊戲有N個副本服務節點提供服務,在生產運行期間,有的節點可能故障,有些節點可能負載過高,有些節點可能故障後自行回複需要能重新上線提供服務。通過consul系統可以隨時讓閘道伺服器或者邏輯伺服器擷取可用的副本服務節點並將請求轉寄到該節點,保持副本服務的高效可用。
其他類型的服務也可以採用同樣的方式進行水平擴充。進一步的,可以在負載高的時候啟動新節點,在負載低的時候關閉部分節點,在雲端服務器上實現這些非常方便,並且由於是按使用計費,通過負載增加或關閉節點也可以避免雲端服務器資源的浪費從而降低費用。
一點問題
服務註冊時設定檢查失敗後30秒登出服務,實際運行中大約80秒才登出服務,原因待查。
2948 次點擊