go微服務框架go-micro深度學習(三) Registry服務的註冊和發現
服務的註冊與發現是微服務必不可少的功能,這樣系統才能有更高的效能,更高的可用性。go-micro框架的服務發現有自己能用的介面Registry。只要實現這個介面就可以定製自己的服務註冊和發現。
go-micro在客戶端做的負載,典型的Balancing-aware Client模式。
服務端把服務的地址資訊儲存到Registry, 然後定時的心跳檢查,或者定時的重新註冊服務。客戶端監聽Registry,最好是把服務資訊儲存到本地,監聽服務的變動,更新快取。當呼叫服務端的介面是時,根據客戶端的服務列表和負載演算法選擇服務端進行通訊。
go-micro的能用Registry介面
type Registry interface { Register(*Service, ...RegisterOption) error Deregister(*Service) error GetService(string) ([]*Service, error) ListServices() ([]*Service, error) Watch(...WatchOption) (Watcher, error) String() string Options() Options } type Watcherinterface { // Next is a blocking call Next() (*Result, error) Stop() }
這個介面還是很簡單明瞭的,看方法也大概能猜到主要的作用
Register方法和Deregister是服務端用於註冊服務的,Watcher介面是客戶端用於監聽服務資訊變化的。
接下來我以go-micro的etcdv3為Registry的例給大家詳細講解一下go-micro的詳細服務發現過程
go-micro 服務端註冊服務
流程圖
服務端看上去流程還是比較簡單的,當服務端呼叫Run()方法時,會呼叫service.Start()方法。這個除了監聽埠,啟動服務,還會把服務的ip埠號資訊,和所有的公開介面的元資料資訊儲存到我們選擇的Register伺服器上去。
看上去沒有問題,但是,如果我們的節點發生故障,也是需要告訴Register把我們的節點資訊刪除掉。
Run()方法中有個go s.run(ex) 方法的呼叫,這個方法就是根據我們設定interval去重新註冊服務,當然比較保險的方式是我們把服務的ttl也設定上,這樣當服務在未知的情況下崩潰,到了ttl的時間Register服務也會自動把資訊刪除掉。
設定服務的ttl和 interval
// 初始化服務 service := micro.NewService( micro.Name(common.ServiceName), micro.RegisterTTL(time.Second*30), micro.RegisterInterval(time.Second*20), micro.Registry(reg), )
ttl就是註冊服務的過期時間,interval就是間隔多久再次註冊服務。如果系統崩潰,過期時間也會把服務刪除掉。客戶端當然也會有想就的判斷,下面會詳細解說
客戶端發現服務
客戶端的服務發現要步驟多一些,但並不複雜,他涉及到服務選擇Selector和服務發現Register兩部分。
Selector是基於服務發現的,根據你選擇的主機選擇演算法,返回主機的資訊。預設的情況,go-micro是每次要得到伺服器主機的資訊都要去Register去獲取。但是檢視cmd.go的原始碼你會發現預設初始化的值,selector的預設flag是cache。DefaultSelectors裡的cache對應的就是初始化cacheSelector方法
但是當你在執行service.Init()方法時
go-micro會把預設的selector替換成cacheSelector,具體的實現是在cmd.go的Before方法裡
cacheSelector 會把從Register裡獲取的主機資訊快取起來。並設定超時時間,如果超時則重新獲取。在獲取主機資訊的時候他會單獨跑一個協程,去watch服務的註冊,如果有新節點發現,則加到快取中,如果有節點故障則刪除快取中的節點資訊。當client還要根據selector選擇的主機選擇演算法才能得到主機資訊,目前只有兩種演算法,迴圈和隨機法。為了增加執行效率,很client端也會設定快取連線池,這個點,以後會詳細說。
所以大概的客戶端服務發現流程是下面這樣
主要的呼叫過程都在Call方法內
主要的思路是
從Selector裡得到選擇主機策略方法next。
根據Retory是否重試呼叫服務,呼叫服務的過程是,從next 方法內得到主機,連線並傳輸資料 ,如果失敗則重試,重試時,會根據主機選擇策略方法next重新得到一個新的主機進行操作。