溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Golang中的consul如何使用

發(fā)布時(shí)間:2023-03-06 15:59:24 來源:億速云 閱讀:189 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Golang中的consul如何使用”,在日常操作中,相信很多人在Golang中的consul如何使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Golang中的consul如何使用”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

    consul

    consul是一個開源服務(wù)注冊和服務(wù)發(fā)現(xiàn)的中心,可以用于微服務(wù)的注冊和服務(wù)之間的調(diào)用的發(fā)現(xiàn),幫助上游服務(wù)找到下游服務(wù)的具體ip:port或者是domain,也可以使用dns的方式讓consul幫你去做轉(zhuǎn)發(fā),具體介紹請看consul的官網(wǎng),consul區(qū)分server-agent和client-agent,client-agent的作用一般來說就是用來轉(zhuǎn)發(fā)到server-agent的,所以本文只啟動server-agent。

    consul的安裝和部署

    consul有兩種部署模式,一種是直接在cvm上安裝consul的bin包,然后以server-agent的模式進(jìn)行啟動,一種是用docker直接啟動鏡像,本文直接使用docker啟動鏡像,將這個鏡像的啟動參數(shù)設(shè)置為server-agent,在這種模式下,如果要使用服務(wù)發(fā)現(xiàn)的功能需要區(qū)分主機(jī)ip和容器ip 不能使用127.0.0.1這種ip去讓server維持go服務(wù)的心跳

    本文使用的cvm系統(tǒng)為centos8,其他Linux發(fā)行版可以自行用包管理工具去安裝一下的前置依賴

    docker安裝

    curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
    systemctl start docker

    使用上文腳本一鍵安裝docker

    consul鏡像的啟動

    docker pull consul
    docker run -d -p 8500:8500 -v ~/consul:/consul/data -e CONSUL_BIND_INTERFACE='eth0' --name=consul1 consul agent -server -bootstrap -ui -client='0.0.0.0'

    兩步啟動一個consul的server-agent,然后就可以通過ip:8500訪問得到consul的一個web界面,如果ip訪問不通可以使用下文的vscode的代理模式去訪問或者是在自己廠商的cvm控制臺去開端口的訪問策略,web界面如下

    Golang中的consul如何使用

    啟動一個tcp_health_check的服務(wù)注冊

    創(chuàng)建一個go項(xiàng)目

    mkdir consul_demo
    go mod init consul_demo
    go get -u github.com/hashicorp/consul/api
    touch main.go

    // main.go
    package main
    
    import (
    	"bufio"
    	"fmt"
    	"net"
    
    	consulapi "github.com/hashicorp/consul/api"
    )
    
    type DiscoveryConfig struct {
    	ID      string
    	Name    string
    	Tags    []string
    	Port    int
    	Address string
    }
    
    var consulAddress = "127.0.0.1:8500"
    
    func RegisterService(dis DiscoveryConfig) error {
    	config := consulapi.DefaultConfig()
    	config.Address = consulAddress
    	client, err := consulapi.NewClient(config)
    	if err != nil {
    		fmt.Printf("create consul client : %v\n", err.Error())
    	}
    	registration := &consulapi.AgentServiceRegistration{
    		ID:      dis.ID,
    		Name:    dis.Name,
    		Port:    dis.Port,
    		Tags:    dis.Tags,
    		Address: dis.Address,
    	}
    	// 啟動tcp的健康檢測,注意address不能使用127.0.0.1或者localhost,因?yàn)閏onsul-agent在docker容器里,如果用這個的話,
    	// consul會訪問容器里的port就會出錯,一直檢查不到實(shí)例
    	check := &consulapi.AgentServiceCheck{}
    	check.TCP = fmt.Sprintf("%s:%d", registration.Address, registration.Port)
    	check.Timeout = "5s"
    	check.Interval = "5s"
    	check.DeregisterCriticalServiceAfter = "60s"
    	registration.Check = check
    
    	if err := client.Agent().ServiceRegister(registration); err != nil {
    		fmt.Printf("register to consul error: %v\n", err.Error())
    		return err
    	}
    	return nil
    }
    
    func startTcp() {
    	ls, err := net.Listen("tcp", ":10111")
    	if err != nil {
    		fmt.Printf("start tcp listener error: %v\n", err.Error())
    		return
    	}
    	for {
    		conn, err := ls.Accept()
    		if err != nil {
    			fmt.Printf("connect error: %v\n", err.Error())
    		}
    		go func(conn net.Conn) {
    			_, err := bufio.NewWriter(conn).WriteString("hello consul")
    			if err != nil {
    				fmt.Printf("write conn error: %v\n", err)
    			}
    		}(conn)
    	}
    }
    func main() {
    	ch := make(chan error)
    	dis := DiscoveryConfig{
    		ID:      "9527",
    		Name:    "main_service",
    		Tags:    []string{"a", "b"},
    		Port:    10111,
    		Address: "192.168.0.124", //通過ifconfig查看本機(jī)的eth0的ipv4地址
    	}
    	go startTcp()
    	RegisterService(dis)
    	// 阻塞等待
    	<-ch
    }

    然后我們運(yùn)行這個代碼

    go run main.go

    就可以看到consul的web界面上多了一個服務(wù)實(shí)例

    Golang中的consul如何使用

    Golang中的consul如何使用

    http版

    如果不使用tcp作為健康檢查的方式,可以使用Http_server去實(shí)現(xiàn),邏輯是一樣的,需要給consul返回一個消息,讓consul確認(rèn)你的心跳即可

    check := &consulapi.AgentServiceCheck{}
    check.HTTP = fmt.Sprintf("http://%s:%d/", registration.Address, registration.Port)
    func startHttp() {
    	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    		fmt.Printf("consul get uri: %s\n", r.RequestURI)
    		w.Write([]byte("hello consul"))
    	})
    	if err := http.ListenAndServe(":10111", nil); err != nil {
    		fmt.Printf("start http server error: %v\n", err)
    	}
    }
    go startHttp()

    Golang中的consul如何使用

    服務(wù)發(fā)現(xiàn)

    服務(wù)發(fā)現(xiàn)其實(shí)就是通過http請求向consul請求指定的service下的實(shí)例,獲取到他們對應(yīng)的ip:port和一些其他的元信息,然后在客戶端根據(jù)需要篩選得出一個ip:port的實(shí)例進(jìn)行通訊,由于向consul發(fā)起http請求的sdk已經(jīng)在consul官方實(shí)現(xiàn)了,所以我們不需要自己建一個httpclient去調(diào)用這些api,而是直接構(gòu)建一個struct交給sdk去查詢即可

    package main
    
    import (
    	"fmt"
    	"testing"
    
    	consulapi "github.com/hashicorp/consul/api"
    )
    
    func Discovery(serviceName string) []*consulapi.ServiceEntry {
    	config := consulapi.DefaultConfig()
    	config.Address = "127.0.0.1:8500"
    	client, err := consulapi.NewClient(config)
    	if err != nil {
    		fmt.Printf("consul client error: %v", err)
    	}
    	service, _, err := client.Health().Service(serviceName, "", false, nil)
    	if err != nil {
    		fmt.Printf("consul client get serviceIp error: %v", err)
    	}
    	return service
    }
    
    func TestDiscoeryFromConsul(t *testing.T) {
    	t.Logf("client discovery start")
    	se := Discovery("main_service")
    	for i := 0; i < len(se); i++ {
    		t.Logf("the instance Node is %+v\n", se[i].Node)
    		t.Logf("the isntance Service is %+v\n", se[i].Service)
    		t.Logf("\n")
    	}
    }

    ut的結(jié)果如下,證明我們通過consul找到了下游服務(wù)的ip:port即可發(fā)起通訊

    [root@hecs-74066 consul_demo]# go test -v main_test.go 
    === RUN   TestDiscoeryFromConsul
        main_test.go:25: client discovery start
        main_test.go:28: the instance Node is &{ID:278ba4f1-0309-fc92-d641-a312b5797779 Node:241f8a20d7fb Address:172.17.0.2 Datacenter:dc1 TaggedAddresses:map[lan:172.17.0.2 lan_ipv4:172.17.0.2 wan:172.17.0.2 wan_ipv4:172.17.0.2] Meta:map[consul-network-segment:] CreateIndex:13 ModifyIndex:16 Partition: PeerName:}
        main_test.go:29: the isntance Service is &{Kind: ID:9527 Service:main_service Tags:[a b] Meta:map[] Port:10111 Address:192.168.0.124 SocketPath: TaggedAddresses:map[lan_ipv4:{Address:192.168.0.124 Port:10111} wan_ipv4:{Address:192.168.0.124 Port:10111}] Weights:{Passing:1 Warning:1} EnableTagOverride:false CreateIndex:43 ModifyIndex:43 ContentHash: Proxy:0xc0000c44d0 Connect:0xc000091a50 PeerName: Namespace: Partition: Datacenter:}
        main_test.go:30: 
    --- PASS: TestDiscoeryFromConsul (0.00s)

    到此,關(guān)于“Golang中的consul如何使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI