etcd實現服務發現

2022-01-15 01:16:14 字數 4093 閱讀 5601

etcd環境安裝與使用文章中介紹了etcd的安裝及v3 api使用,本篇將介紹如何使用etcd實現服務發現功能。

服務發現要解決的也是分布式系統中最常見的問題之一,即在同乙個分布式集群中的程序或服務,要如何才能找到對方並建立連線。本質上來說,服務發現就是想要了解集群中是否有程序在監聽 udp 或 tcp 埠,並且通過名字就可以查詢和連線。

服務發現需要實現一下基本功能:

接下來介紹如何使用etcd實現服務發現。

根據etcd的v3 api,當啟動乙個服務時候,我們把服務的位址寫進etcd,註冊服務。同時繫結租約(lease),並以續租約(keep leases alive)的方式檢測服務是否正常執行,從而實現健康檢查。

go**實現:

package main

import (

"context"

"log"

"time"

"go.etcd.io/etcd/clientv3"

)//serviceregister 建立租約註冊服務

type serviceregister struct

//newserviceregister 新建註冊服務

func newserviceregister(endpoints string, key, val string, lease int64) (*serviceregister, error) )

if err != nil

ser := &serviceregister

//申請租約設定時間keepalive

if err := ser.putkeywithlease(lease); err != nil

return ser, nil

}//設定租約

func (s *serviceregister) putkeywithlease(lease int64) error

//註冊服務並繫結租約

_, err = s.cli.put(context.background(), s.key, s.val, clientv3.withlease(resp.id))

if err != nil

//設定續租 定期傳送需求請求

leaserespchan, err := s.cli.keepalive(context.background(), resp.id)

if err != nil

s.leaseid = resp.id

log.println(s.leaseid)

s.keepalivechan = leaserespchan

log.printf("put key:%s val:%s success!", s.key, s.val)

return nil

}//listenleaserespchan 監聽 續租情況

func (s *serviceregister) listenleaserespchan()

log.println("關閉續租")

}// close 登出服務

func (s *serviceregister) close() error

log.println("撤銷租約")

return s.cli.close()

}func main()

ser, err := newserviceregister(endpoints, "/web/node1", "localhost:8000", 5)

if err != nil

//監聽續租相應chan

go ser.listenleaserespchan()

select

}

主動退出服務時,可以呼叫close()方法,撤銷租約,從而登出服務。

根據etcd的v3 api,很容易想到使用watch監視某類服務,通過watch感知服務的新增修改刪除操作,修改服務列表。

)//servicediscovery 服務發現

type servicediscovery struct

//newservicediscovery 新建發現服務

func newservicediscovery(endpoints string) *servicediscovery )

if err != nil

return &servicediscovery

}//watchservice 初始化服務列表和監視

func (s *servicediscovery) watchservice(prefix string) error

for _, ev := range resp.kvs

//監視字首,修改變更的server

go s.watcher(prefix)

return nil

}//watcher 監聽字首

func (s *servicediscovery) watcher(prefix string)

} }}//setservicelist 新增服務位址

func (s *servicediscovery) setservicelist(key, val string)

//delservicelist 刪除服務位址

func (s *servicediscovery) delservicelist(key string)

//getservices 獲取服務位址

func (s *servicediscovery) getservices() string

return addrs

}//close 關閉服務

func (s *servicediscovery) close() error

func main()

ser := newservicediscovery(endpoints)

defer ser.close()

ser.watchservice("/web/")

ser.watchservice("/grpc/")

for

}}執行:

#執行服務發現

$go run discovery.go

watching prefix:/web/ now...

put key : /web/node1 val:localhost:8000

[localhost:8000]

#另乙個終端執行服務註冊

$go run register.go

put key:/web/node1 val:localhost:8000 success!

續約成功 cluster_id:14841639068965178418 member_id:10276657743932975437 revision:29 raft_term:7

續約成功 cluster_id:14841639068965178418 member_id:10276657743932975437 revision:29 raft_term:7

...

基於 raft 演算法的 etcd 天生是乙個強一致性高可用的服務儲存目錄,使用者可以在 etcd 中註冊服務,並且對註冊的服務設定key ttl,定時保持服務的心跳以達到監控健康狀態的效果。通過在 etcd 指定的主題下註冊的服務也能在對應的主題下查詢到。

為了確保連線,我們可以在每個服務機器上都部署乙個 proxy 模式的 etcd,這樣就可以確保能訪問 etcd 集群的服務都能互相連線。

參考:

用etcd實現服務註冊和發現

系統中實現服務註冊與發現所需的基本功能有 在分布式系統中,如何管理節點間的狀態一直是乙個難題,etcd 是由開發並維護的,它使用 go 語言編寫,並通過raft 一致性演算法處理日誌複製以保證強一致性。etcd像是專門為集群環境的服務發現和註冊而設計,它提供了資料 ttl 失效 資料改變監視 多值 ...

服務發現系統etcd介紹

一 概述 etcd是乙個高可用的鍵值儲存系統,主要用於共享配置和服務發現。etcd是由coreos開發並維護的,靈感來自於 zookeeper 和 doozer,它使用go語言編寫,並通過raft一致性演算法處理日誌複製以保證強一致性。raft是乙個新的一致性演算法,適用於分布式系統的日誌複製,ra...

服務發現系統etcd介紹

一 概述 etcd是乙個高可用的鍵值儲存系統,主要用於共享配置和服務發現。etcd是由coreos開發並維護的,靈感來自於 zookeeper 和 doozer,它使用go語言編寫,並通過raft一致性演算法處理日誌複製以保證強一致性。raft是乙個新的一致性演算法,適用於分布式系統的日誌複製,ra...