go Consul服務治理

目前市面上常見的服務治理有consul,etcd,zookeeper,euerka,咱們須要根據本身的服務特色選擇本身相對合適的服務治理工具。java

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集成 已支持 已支持 已支持 已支持

調研一個工具須要看到其優勢,更須要看到其缺點,當服務優勢大於自身業務需求缺點,且缺點有對應的解決方案時,咱們能夠傾向於考慮。node

euerka 聽說如今已中止維護,決定不考慮使用。nginx

zookeeper 爲java開發的,須要java環境,相對比較複雜,優先級較低。git

etcd 與consul爲go開發,部署簡單,功能相對更符合自身業務的需求。github

consul監控檢查更爲豐富,支持多數據中心,webui查看等,配合consul-template實現nginx動態負載均衡等特色更符合自身業務需求,由於決定選用consul做爲業務的服務治理工具。

web

使用consul,其主要有四大特性:spring

1. 服務發現:利用服務註冊,服務發現功能來實現服務治理。bootstrap

2. 健康檢查:利用consul註冊的檢查檢查函數或腳原本判斷服務是否健康,若服務不存在則從註冊中心移除該服務,減小故障服務請求。api

3. k/v數據存儲:存儲kv數據,能夠做爲服務配置中心來使用。安全

4. 多數據中心:能夠創建多個consul集羣經過inter網絡進行互聯,進一步保證數據可用性。

本人也是剛開始學習consul,感受使用consul主要也就是兩大做用,服務註冊發現,配置共享。

 

如今開始學習consul:

啓動單機consul:consul agent -server -bootstrap-expect=1 -data-dir=data -node=consul -bind=x172.16.242.129-ui -client=0.0.0.0

咱們可已經過consul --help 修改一些配置信息,好比集羣個數,綁定地址,數據存放地址,配置文件地址,加入集羣等配置

啓動consul後咱們能夠經過web查看consul運行情況:http://172.16.242.129:8500/ui/dc1/nodes

 

服務啓動後,如今開始測試consul的第一個功能:服務註冊發現,本人使用的爲go語言, 下面主要爲服務註冊,發現的一個demo, 須要注意的是,根據自身的實際配置去修改consul的地址信息和要註冊服務的地址信息

package main

import (
	"github.com/gin-gonic/gin"

	consulapi "github.com/hashicorp/consul/api"
	"net/http"
	"fmt"
	"log"
)

func main() {
	r := gin.Default()

	// consul健康檢查回調函數
	r.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "ok",
		})
	})


	// 註冊服務到consul
	ConsulRegister()

	// 從consul中發現服務
	ConsulFindServer()

	// 取消consul註冊的服務
	//ConsulDeRegister()


	http.ListenAndServe(":8081", r)
}

// 註冊服務到consul
func ConsulRegister()  {
	// 建立鏈接consul服務配置
	config := consulapi.DefaultConfig()
	config.Address = "172.16.242.129:8500"
	client, err := consulapi.NewClient(config)
	if err != nil {
		log.Fatal("consul client error : ", err)
	}

	// 建立註冊到consul的服務到
	registration := new(consulapi.AgentServiceRegistration)
	registration.ID = "111"
	registration.Name = "go-consul-test"
	registration.Port = 8081
	registration.Tags = []string{"go-consul-test"}
	registration.Address = "10.13.153.128"

	// 增長consul健康檢查回調函數
	check := new(consulapi.AgentServiceCheck)
	check.HTTP = fmt.Sprintf("http://%s:%d", registration.Address, registration.Port)
	check.Timeout = "5s"
	check.Interval = "5s"
	check.DeregisterCriticalServiceAfter = "30s" // 故障檢查失敗30s後 consul自動將註冊服務刪除
	registration.Check = check

	// 註冊服務到consul
	err = client.Agent().ServiceRegister(registration)
}

// 取消consul註冊的服務
func ConsulDeRegister()  {
	// 建立鏈接consul服務配置
	config := consulapi.DefaultConfig()
	config.Address = "172.16.242.129:8500"
	client, err := consulapi.NewClient(config)
	if err != nil {
		log.Fatal("consul client error : ", err)
	}

	client.Agent().ServiceDeregister("111")
}

// 從consul中發現服務
func ConsulFindServer()  {
	// 建立鏈接consul服務配置
	config := consulapi.DefaultConfig()
	config.Address = "172.16.242.129:8500"
	client, err := consulapi.NewClient(config)
	if err != nil {
		log.Fatal("consul client error : ", err)
	}

	// 獲取全部service
	services, _ := client.Agent().Services()
	for _, value := range services{
		fmt.Println(value.Address)
		fmt.Println(value.Port)
	}

	fmt.Println("=================================")
	// 獲取指定service
	service, _, err := client.Agent().Service("111", nil)
	if err == nil{
		fmt.Println(service.Address)
		fmt.Println(service.Port)
	}

}

func ConsulCheckHeath()  {
	// 建立鏈接consul服務配置
	config := consulapi.DefaultConfig()
	config.Address = "172.16.242.129:8500"
	client, err := consulapi.NewClient(config)
	if err != nil {
		log.Fatal("consul client error : ", err)
	}

	// 健康檢查
	a, b, _ := client.Agent().AgentHealthServiceByID("111")
	fmt.Println(a)
	fmt.Println(b)
}

func ConsulKVTest()  {
	// 建立鏈接consul服務配置
	config := consulapi.DefaultConfig()
	config.Address = "172.16.242.129:8500"
	client, err := consulapi.NewClient(config)
	if err != nil {
		log.Fatal("consul client error : ", err)
	}

	// KV, put值
	values := "test"
	key := "go-consul-test/172.16.242.129:8100"
	client.KV().Put(&consulapi.KVPair{Key:key, Flags:0, Value: []byte(values)}, nil)

	// KV get值
	data, _, _ := client.KV().Get(key, nil)
	fmt.Println(string(data.Value))

	// KV list
	datas, _ , _:= client.KV().List("go", nil)
	for _ , value := range datas{
		fmt.Println(value)
	}
	keys, _ , _ := client.KV().Keys("go", "", nil)
	fmt.Println(keys)
}

咱們可根據上述功能去實現一個服務註冊,服務發現,配置共享的功能,咱們能夠圍繞這些根據自身業務需求進行靈活的變更,我的想法:根據此功能專門作一個服務管理的模塊,客戶端註冊服務到服務模塊,服務管理去提供其餘模塊的服務發現的功能,同時跟監控結合,當服務不可用時,或服務不存在時,經過監控通知相關人員,咱們也可使用頁面跟咱們服務管理結合,經過前臺服務錄入形式進行註冊服務等等。

 

假如公司服務使用nginx負載均衡的話,咱們可與consul和consul-template結合,動態生成nginx的配置文件,而後從新reload nginx,實現nginx的動態負載均衡。

固然還有其餘方式實現nginx的動態負載均衡,如使用nginx-upsync-module和consul,openResty的lua腳本實現nginx動態負載均衡。

相關文章
相關標籤/搜索