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...