go-micro使用Consul做服務(wù)發(fā)現(xiàn)的方法和原理

go-micro v4默認(rèn)使用mdns做服務(wù)發(fā)現(xiàn)。不過(guò)也支持采用其它的服務(wù)發(fā)現(xiàn)中間件踢代,因?yàn)槎嗄陙?lái)一直使用Consul做服務(wù)發(fā)現(xiàn)盲憎,為了方便和其它服務(wù)集成,所以還是選擇了Consul胳挎。這篇文章將介紹go-micro使用Consul做服務(wù)發(fā)現(xiàn)的方法饼疙。關(guān)于Consul的使用方式請(qǐng)參考我的另一篇文章:使用Consul做服務(wù)發(fā)現(xiàn)的若干姿勢(shì)

安裝Consul

如果你已經(jīng)安裝Consul慕爬,或者對(duì)Consul很熟悉了窑眯,按照自己的方式處理Consul就行了。

這里提供一個(gè)通過(guò)docker快速安裝Consul的方式澡罚,當(dāng)然前提是你得安裝了docker伸但。

執(zhí)行命令:

docker run --name consul1 -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302  -d consul:latest

這會(huì)在docker容器中啟動(dòng)一個(gè)最新版本的Consul服務(wù),并將相關(guān)端口開(kāi)放給主機(jī)留搔。

安裝Consul插件

使用Consul作為服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)更胖,需要先安裝go-micro的consul插件:

go get github.com/go-micro/plugins/v4/registry/consul

服務(wù)端使用Consul

服務(wù)注冊(cè)

為了使用Consul做服務(wù)注冊(cè),需要為go-micro server顯式的指定Consul Registry隔显。直接看代碼吧:

func main() {

    registry := consul.NewRegistry()

    rpcServer := server.NewServer(
        server.Name("registry-consul.service"),
        server.Address("0.0.0.0:8001"),
        server.Registry(registry),
    )

    proto.RegisterHelloHandler(rpcServer, &Hello{})

    service := micro.NewService(
        micro.Server(rpcServer),
    )

    service.Init()

    // Run server
    if err := service.Run(); err != nil {
        log.Fatal(err)
    }
}

通過(guò) consul.NewRegistry() 創(chuàng)建一個(gè)Consul 注冊(cè)中心却妨,然后使用 server.NewServer 創(chuàng)建Server的時(shí)候把它設(shè)置進(jìn)去;同時(shí)我們需要指定服務(wù)的名稱(chēng)括眠,這里設(shè)置的是 registry-consul.service彪标;另外這里不使用隨機(jī)端口,指定了一個(gè)服務(wù)的監(jiān)聽(tīng)地址掷豺。這樣基本就OK了捞烟。

img

這里并沒(méi)有指定Consul的連接地址,因?yàn)榘凑胀扑]的Consul部署方式当船,服務(wù)所在機(jī)器或者容器中應(yīng)該部署一個(gè)Consul的客戶(hù)端题画,程序可以直接通過(guò) 127.0.0.1:8500 訪問(wèn)到它。如果要顯示指定德频,可以在NewRegistry時(shí)設(shè)置:

    registry := consul.NewRegistry(
        registry.Addrs("127.0.0.1:8500"),
    )

注冊(cè)過(guò)程

通過(guò)一張圖來(lái)看一下苍息,go-micro注冊(cè)服務(wù)到Consul時(shí)都做了什么。

img

服務(wù)注冊(cè)關(guān)鍵是實(shí)現(xiàn)兩個(gè)動(dòng)作:

1、注冊(cè): rpcServer啟動(dòng)的時(shí)候竞思,會(huì)調(diào)用到自身的Register方法表谊,Register方法會(huì)調(diào)用consul插件的Register方法,然后調(diào)用到consul自身SDK提供的Agent.ServiceRegister方法盖喷,將服務(wù)注冊(cè)到Consul中爆办。注冊(cè)的服務(wù)名稱(chēng)就是NewServer時(shí)的server.Name。

2传蹈、健康上報(bào): 即刷新TTL押逼,服務(wù)注冊(cè)成功后,會(huì)啟動(dòng)一個(gè)定時(shí)器定時(shí)調(diào)用consul插件的Register方法惦界,這個(gè)方法內(nèi)部判斷服務(wù)注冊(cè)過(guò)挑格,則會(huì)調(diào)用consul自身SDK提供的Agent.PassTTL方法,刷新Consul中對(duì)應(yīng)服務(wù)的TTL沾歪。

健康檢查

go-micro服務(wù)的健康狀態(tài)是通過(guò)TTL維護(hù)的漂彤,服務(wù)需要定時(shí)去刷新TTL,如果TTL超過(guò)指定的時(shí)間沒(méi)有被刷新灾搏,則服務(wù)會(huì)被認(rèn)為是不健康的挫望。默認(rèn)情況下有三個(gè)設(shè)置會(huì)涉及到TTL,還是先來(lái)看代碼:

registry := consul.NewRegistry()

    regCheckFunc := func(ctx context.Context) error {
        fmt.Println(time.Now().Format("2006-01-02 15:04:05") + " do register check")
        if 1+1 == 2 {
            return nil
        }
        return errors.New("this not earth")
    }

    rpcServer := server.NewServer(
        server.Name("registry-consul.service"),
        server.Address("0.0.0.0:8001"),
        server.Registry(registry),
        server.RegisterCheck(regCheckFunc),
        server.RegisterInterval(10*time.Second),
        server.RegisterTTL(20*time.Second),
    )

    proto.RegisterHelloHandler(rpcServer, &Hello{})

    service := micro.NewService(
        micro.Server(rpcServer),
    )

    //service.Init()

    if err := service.Run(); err != nil {
        log.Fatal(err)
    }

關(guān)于這三個(gè)設(shè)置狂窑,這里簡(jiǎn)單介紹下:

**1媳板、server.RegisterCheck(regCheckFunc) ** 服務(wù)刷新TTL之前,會(huì)調(diào)用一個(gè)函數(shù)檢查服務(wù)的狀態(tài)泉哈,這個(gè)函數(shù)的返回值是error類(lèi)型蛉幸。默認(rèn)的函數(shù)不進(jìn)行任何檢查,直接返回nil丛晦,代表服務(wù)狀態(tài)正常奕纫;我們可以自己寫(xiě)一個(gè)函數(shù),進(jìn)行一些檢查邏輯烫沙,比如是否要下線維護(hù)匹层。如果返回的error不是nil,go-micro會(huì)嘗試在Consul中注銷(xiāo)服務(wù)锌蓄,則調(diào)用方將不會(huì)再訪問(wèn)到這個(gè)服務(wù)節(jié)點(diǎn)升筏。

2、server.RegisterInterval(10*time.Second) 這個(gè)設(shè)置指定程序去刷新TLL的頻率瘸爽。

3仰冠、server.RegisterTTL(20*time.Second) 這個(gè)設(shè)置指定TTL的生存周期,如果超過(guò)這個(gè)時(shí)間沒(méi)有刷新TTL蝶糯,則Consul會(huì)認(rèn)為服務(wù)是不健康。

另外需要注意不要使用service.Init()辆沦,因?yàn)檫@里邊會(huì)覆蓋 RegisterIntervalRegisterTTL 的設(shè)置昼捍,除非你不關(guān)心這兩個(gè)參數(shù)识虚。關(guān)于這個(gè)問(wèn)題可以參考:https://github.com/asim/go-micro/issues/2488

客戶(hù)端使用Consul

調(diào)用服務(wù)

為了使用Consul做服務(wù)發(fā)現(xiàn),需要為go-micro service顯式的指定Consul Registry妒茬。還是直接看代碼:

    registry := consul.NewRegistry()

    service := micro.NewService(
        micro.Client(client.NewClient()),
        micro.Registry(registry),
    )

    service.Init()
    client := proto.NewHelloService("registry-consul.service", service.Client())

    rsp, err := client.Say(context.TODO(), &proto.SayRequest{Name: "BOSSMA"})
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(rsp)

代碼很簡(jiǎn)單担锤,指定consul作為服務(wù)發(fā)現(xiàn)組件后,調(diào)用服務(wù)的時(shí)候傳遞的服務(wù)名稱(chēng)就會(huì)使用consul進(jìn)行解析乍钻,獲取到IP肛循、端口后,再進(jìn)行實(shí)際調(diào)用银择。

發(fā)現(xiàn)過(guò)程

還是先來(lái)看張圖多糠,從調(diào)用 XXXService 的方法 YYY 開(kāi)始:

e6c9d24ely1h1lmywl9pwj20u014zgp4.jpeg

整個(gè)過(guò)程分為兩個(gè)大的步驟,第一步獲取要調(diào)用服務(wù)的地址浩考,第二步通過(guò)http請(qǐng)求調(diào)用服務(wù)夹孔。我們重點(diǎn)看第一步通過(guò)Consul獲取服務(wù)這塊。

首先進(jìn)入一個(gè)Selector析孽,就是選擇器的意思搭伤。Selector首先看緩存中有沒(méi)有緩存請(qǐng)求服務(wù)的地址信息,如果沒(méi)有就去Consul查詢(xún)袜瞬,查詢(xún)到之后再通過(guò)指定的選擇策略選出來(lái)一個(gè)地址怜俐,用于后續(xù)http請(qǐng)求。這里默認(rèn)的選擇策略是隨機(jī)選擇邓尤,比如查詢(xún)到這個(gè)服務(wù)有三個(gè)部署節(jié)點(diǎn)拍鲤,隨機(jī)策略會(huì)隨機(jī)返回其中某一個(gè)地址。

除了隨機(jī)策略裁赠,go-micro還提供了一個(gè)輪詢(xún)策略殿漠,這時(shí)候需要自己創(chuàng)建一個(gè)Selector:

    registry := consul.NewRegistry()
    selector := selector.NewSelector(
        selector.SetStrategy(selector.RoundRobin),
        selector.Registry(registry),
    )

    service := micro.NewService(
        micro.Client(client.NewClient()),
        micro.Selector(selector),
        //micro.Registry(registry),
    )

另外從上面的示意圖中,我們可以看到Selector調(diào)用了Registry佩捞,所以這里創(chuàng)建Selector的時(shí)候绞幌,我們把Registry設(shè)置了進(jìn)去,然后再把創(chuàng)建的Selector設(shè)置到Service中一忱。其實(shí)還有另一種方式莲蜘,把設(shè)置Registry放到設(shè)置Selector后邊,同樣可以把Registry注冊(cè)到Selector中帘营,但是這樣比較隱晦票渠,還需要注意設(shè)置順序,我不推薦芬迄。不過(guò)如果在Selector之外需要使用Registry的時(shí)候问顷,還是需要使用micro.Registry(registry)進(jìn)行注冊(cè),這個(gè)例子中并沒(méi)有相關(guān)場(chǎng)景。

效果展示

先啟動(dòng)服務(wù)端杜窄,然后啟動(dòng)客戶(hù)端肠骆,截圖如下:

img

以上就是本文的主要內(nèi)容,如有錯(cuò)漏歡迎反饋塞耕。

演示代碼已上傳到Github:https://github.com/bosima/go-demo/tree/main/go-micro-registry-consul

收獲更多架構(gòu)知識(shí)蚀腿,請(qǐng)關(guān)注公眾號(hào) 螢火架構(gòu)。原創(chuàng)內(nèi)容扫外,轉(zhuǎn)載請(qǐng)注明出處莉钙。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市筛谚,隨后出現(xiàn)的幾起案子磁玉,更是在濱河造成了極大的恐慌,老刑警劉巖刻获,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜀涨,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蝎毡,警方通過(guò)查閱死者的電腦和手機(jī)厚柳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沐兵,“玉大人别垮,你說(shuō)我怎么就攤上這事≡眩” “怎么了碳想?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)毁靶。 經(jīng)常有香客問(wèn)我胧奔,道長(zhǎng),這世上最難降的妖魔是什么预吆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任龙填,我火速辦了婚禮,結(jié)果婚禮上拐叉,老公的妹妹穿的比我還像新娘岩遗。我一直安慰自己,他們只是感情好凤瘦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布宿礁。 她就那樣靜靜地躺著,像睡著了一般蔬芥。 火紅的嫁衣襯著肌膚如雪梆靖。 梳的紋絲不亂的頭發(fā)上控汉,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音返吻,去河邊找鬼暇番。 笑死,一個(gè)胖子當(dāng)著我的面吹牛思喊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播次酌,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼恨课,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了岳服?” 一聲冷哼從身側(cè)響起剂公,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吊宋,沒(méi)想到半個(gè)月后纲辽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡璃搜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年拖吼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片这吻。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吊档,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出唾糯,到底是詐尸還是另有隱情怠硼,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布移怯,位于F島的核電站香璃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏舟误。R本人自食惡果不足惜葡秒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脐帝。 院中可真熱鬧同云,春花似錦、人聲如沸堵腹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)疚顷。三九已至旱易,卻和暖如春禁偎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阀坏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工如暖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人忌堂。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓盒至,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親士修。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枷遂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容