最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解Golang中consul的基本使用

 更新時(shí)間:2023年03月06日 14:33:00   作者:白象孫國(guó)帥  
consul是一個(gè)開(kāi)源服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)的中心,可以用于微服務(wù)的注冊(cè)和服務(wù)之間的調(diào)用的發(fā)現(xiàn),幫助上游服務(wù)找到下游服務(wù)的具體ip:port或者是domain,也可以使用dns的方式讓consul幫你去做轉(zhuǎn)發(fā)。本文就來(lái)講講它的具體使用吧

consul

consul是一個(gè)開(kāi)源服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)的中心,可以用于微服務(wù)的注冊(cè)和服務(wù)之間的調(diào)用的發(fā)現(xiàn),幫助上游服務(wù)找到下游服務(wù)的具體ip:port或者是domain,也可以使用dns的方式讓consul幫你去做轉(zhuǎn)發(fā),具體介紹請(qǐng)看consul的官網(wǎng),consul區(qū)分server-agent和client-agent,client-agent的作用一般來(lái)說(shuō)就是用來(lái)轉(zhuǎn)發(fā)到server-agent的,所以本文只啟動(dòng)server-agent,他們的詳細(xì)差距可以在google上查到,本文基于golang實(shí)現(xiàn)一個(gè)服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)的demo。demo地址

consul的安裝和部署

consul有兩種部署模式,一種是直接在cvm上安裝consul的bin包,然后以server-agent的模式進(jìn)行啟動(dòng),一種是用docker直接啟動(dòng)鏡像,本文直接使用docker啟動(dòng)鏡像,將這個(gè)鏡像的啟動(dòng)參數(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鏡像的啟動(dòng)

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'

兩步啟動(dòng)一個(gè)consul的server-agent,然后就可以通過(guò)ip:8500訪問(wèn)得到consul的一個(gè)web界面,如果ip訪問(wèn)不通可以使用下文的vscode的代理模式去訪問(wèn)或者是在自己廠商的cvm控制臺(tái)去開(kāi)端口的訪問(wèn)策略,web界面如下

啟動(dòng)一個(gè)tcp_health_check的服務(wù)注冊(cè)

創(chuàng)建一個(gè)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,
	}
	// 啟動(dòng)tcp的健康檢測(cè),注意address不能使用127.0.0.1或者localhost,因?yàn)閏onsul-agent在docker容器里,如果用這個(gè)的話,
	// consul會(huì)訪問(wèn)容器里的port就會(huì)出錯(cuò),一直檢查不到實(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", //通過(guò)ifconfig查看本機(jī)的eth0的ipv4地址
	}
	go startTcp()
	RegisterService(dis)
	// 阻塞等待
	<-ch
}

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

go run main.go

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

http版

如果不使用tcp作為健康檢查的方式,可以使用Http_server去實(shí)現(xiàn),邏輯是一樣的,需要給consul返回一個(gè)消息,讓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()

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

服務(wù)發(fā)現(xiàn)其實(shí)就是通過(guò)http請(qǐng)求向consul請(qǐng)求指定的service下的實(shí)例,獲取到他們對(duì)應(yīng)的ip:port和一些其他的元信息,然后在客戶端根據(jù)需要篩選得出一個(gè)ip:port的實(shí)例進(jìn)行通訊,由于向consul發(fā)起http請(qǐng)求的sdk已經(jīng)在consul官方實(shí)現(xiàn)了,所以我們不需要自己建一個(gè)httpclient去調(diào)用這些api,而是直接構(gòu)建一個(gè)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é)果如下,證明我們通過(guò)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的基本使用的文章就介紹到這了,更多相關(guān)Golang consul內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang程序如何查找內(nèi)存泄漏(pprof)

    Golang程序如何查找內(nèi)存泄漏(pprof)

    該文章詳細(xì)介紹了如何使用Golang的pprof工具查找內(nèi)存泄漏,首先,在main包中引入pprof包并設(shè)置條件編譯,然后編譯程序并運(yùn)行,通過(guò)執(zhí)行g(shù)otoolpprof-inuse_space命令,可以進(jìn)入交互模式并使用top命令查看內(nèi)存分配最多的函數(shù),如果本機(jī)中有源代碼
    2024-12-12
  • 手把手帶你走進(jìn)Go語(yǔ)言之語(yǔ)法基礎(chǔ)解析

    手把手帶你走進(jìn)Go語(yǔ)言之語(yǔ)法基礎(chǔ)解析

    這篇文章主要介紹了手把手帶你走進(jìn)Go語(yǔ)言之語(yǔ)法基礎(chǔ),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • golang?Gorm框架講解

    golang?Gorm框架講解

    gorm是一個(gè)使用Go語(yǔ)言編寫的ORM框架,這篇文章主要介紹了golang?Gorm框架,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • Go內(nèi)存分配之結(jié)構(gòu)體優(yōu)化技巧

    Go內(nèi)存分配之結(jié)構(gòu)體優(yōu)化技巧

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言內(nèi)存分配之結(jié)構(gòu)體優(yōu)化技巧的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • 使用自定義錯(cuò)誤碼攔截grpc內(nèi)部狀態(tài)碼問(wèn)題

    使用自定義錯(cuò)誤碼攔截grpc內(nèi)部狀態(tài)碼問(wèn)題

    這篇文章主要介紹了使用自定義錯(cuò)誤碼攔截grpc內(nèi)部狀態(tài)碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Go語(yǔ)言基礎(chǔ)for循環(huán)語(yǔ)句的用法及示例詳解

    Go語(yǔ)言基礎(chǔ)for循環(huán)語(yǔ)句的用法及示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言基礎(chǔ)for循環(huán)語(yǔ)句的用法及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • go語(yǔ)言中五種字符串的拼接方式(小結(jié))

    go語(yǔ)言中五種字符串的拼接方式(小結(jié))

    字符串拼接在 golang 里面其實(shí)有很多種實(shí)現(xiàn),本文就詳細(xì)的介紹一下go語(yǔ)言中五種字符串的拼接方式以及性能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • go chan基本使用詳解

    go chan基本使用詳解

    本文主要介紹了go chan基本使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Go設(shè)計(jì)模式之觀察者模式講解和代碼示例

    Go設(shè)計(jì)模式之觀察者模式講解和代碼示例

    觀察者是一種行為設(shè)計(jì)模式, 允許一個(gè)對(duì)象將其狀態(tài)的改變通知其他對(duì)象,觀察者模式提供了一種作用于任何實(shí)現(xiàn)了訂閱者接口的對(duì)象的機(jī)制, 可對(duì)其事件進(jìn)行訂閱和取消訂閱,本文就通過(guò)代碼示例給大家詳細(xì)介紹一下Go的觀察者模式,需要的朋友可以參考下
    2023-07-07
  • 一文詳解Golang如何解決內(nèi)存溢出

    一文詳解Golang如何解決內(nèi)存溢出

    內(nèi)存溢出是指程序在運(yùn)行時(shí)超出了分配給它的內(nèi)存限制,從而導(dǎo)致程序異常或崩潰的現(xiàn)象,本文主要為大家介紹了Golang解決內(nèi)存溢出的方法,感興趣的小伙伴可以了解下
    2025-01-01

最新評(píng)論

达尔| 汝州市| 水城县| 巫山县| 祥云县| 上饶县| 大丰市| 宁国市| 克东县| 福州市| 平谷区| 石阡县| 浠水县| 奉新县| 福海县| 凭祥市| 廊坊市| 镇巴县| 绥宁县| 富川| 沾益县| 茶陵县| 阿拉善左旗| 兴仁县| 镇雄县| 常州市| 织金县| 股票| 乐昌市| 昌江| 宁波市| 姚安县| 尚义县| 昌邑市| 隆回县| 和静县| 孟村| 望奎县| 瓦房店市| 紫金县| 株洲县|