我來教你如何給注冊中心錦上添花?
hello,大家好,我是小樓。
在上一篇文章《??如何組裝一個注冊中心??》中,我們看到了如何利用一些現有的技術方案來組裝出一個生產可用的注冊中心最小集。
有的同學看完表示學到了,也有同學直呼不過癮,能不能手寫一個注冊中心?能不能繼續展開說說?
由于精力有限,手寫一個注冊中心暫時還不行,展開說說倒是可以滿足。
于是本期打算以注冊中心的周邊能力展開說說,這些能力屬于錦上添花,沒有它們注冊中心可以正常運行,有了它們也不一定變得更強,但一定會更加花里胡哨。
那可能有讀者會問,花里胡哨的有什么用呢?我覺得主要是了解一些新的、奇怪的知識,說不定哪天能用上呢,是吧?
控制臺
如果想讓注冊中心變得花里胡哨,首先肯定是開發一個控制臺,控制臺的基本功能就是展示服務的消費者與提供者,展示的用處有查找服務,排查問題等等,下圖是Nacos的控制臺:
除了基本的展示功能,我們還可以在控制臺上搞些別的事情,比如下面這些。
服務配置
配置本不是注冊中心必備的功能,配置一般由配置中心管理,但配置中心似乎又和注冊中心脫不了干系,Nacos就是一個集注冊中心和配置中心于一體的組件。
注冊中心也可以做一點和服務相關配置的事情,比如服務的超時時間、熔斷降級等等元數據,不過要注意的是注冊中心本身只能保存、修改,至于這些配置真正起作用的還是得和RPC框架配合。
可能你會問,為什么注冊中心要去做配置中心的事兒呢?這不是職責不清?
可以這么理解,服務發現基本是個服務都要接入,但配置中心可不一定要接,如果只想做點簡單的服務相關的動態配置,引入一個配置中心是有點重。
如果是公司生產級的服務配置,最好再附帶上一個灰度的能力,如果一次下發配置到全部機器,可能會出現故障,所以需要一種灰度下發的機制,分批下發,控制風險。
事件追蹤
說到問題排查,光展示提供者、消費者可能還不夠,有時候啟動一個提供者,消費者就是沒感知到,或者很久之后才感知到,這時有點摸不著頭腦,如果我們拿出這個事件的時間線,哪個環節出問題便一目了然。
在Nacos的企業版中就支持了類似的推送軌跡功能,當然這么好的功能,肯定是收費項。
拓撲關系
可能我們忽略了注冊中心的繪制服務之間的拓撲關系的能力,開源注冊中心基本沒提到這個,一般來說拓撲關系是鏈路追蹤的活。
注冊中心其實也大致可以干這個活,不過注冊中心是按照服務的訂閱關系繪制出來,并不是按照真實的調用關系,但這幾乎也近似調用關系了,有了這個,我們就可以去做一些服務治理相關的事了,比如循環依賴、依賴層級太深等問題都可以看出來。
流量控制
流量控制也不一定非要在注冊中心上做,比如Dubbo就是在RPC框架上做了很多流量相關的事情,像集群的選擇、路由、負載均衡等。
如果RPC框架沒這么強大的能力,或者RPC框架是多語言的實現,能力尚未打平,那么在注冊中心上實現也是一個不錯的選擇。
路由偏好
路由偏好簡單來說,如果提供者有多個集群,挑選一個更適合的集群來提供服務,這就叫路由偏好。
舉個例子,例如消費者在杭州,提供者有兩個集群,一個在上海,一個在北京,這兩個機房提供的服務完全對等,這時消費者更適合調用本地的集群,這樣時延更小。
當然我們還可以根據服務器的性能、甚至自定義的規則來做路由偏好。
動態切流
有了上面路由偏好的鋪墊,想必你也能想到一個場景,萬一有一天上海的提供者不可用了,我們可以通過對注冊中心的干預,手動把北京的提供者下發給消費者,實現一個客戶端無侵入的動態切流。
流量劫持
流量劫持和動態切流的原理一樣,實現也基本差不多,只不過下發的數據不太一樣,原先的提供者列表,被注冊中心偷天換日,換成了本地的一個端口127.0.0.1:8001。
這樣替換有什么作用呢?比如用agent來承接流量,像service mesh都有這種需求,注冊中心就可以完成流量劫持。
其實劫持還有其他作用,如果服務的提供方壓力太大,想降級,但消費者和提供者都沒有降級能力,眼看著服務快掛了,千鈞一發之際,你想到了注冊中心,手動下發一個不存在的提供者地址,讓消費者請求報錯,以保護其他服務正常運行,這些奇奇怪怪的想法說不定都可以在注冊中心上實現。
探活
探活算是注冊中心的一個小功能,我們看看在這個小功能上還能玩出什么花樣。
探活擴展
最簡單的探活是端口探活,即注冊中心向提供者注冊的端口發起TCP連接請求,如果能成功建立連接說明服務正常。但有時又不是這樣,比如服務僵死,端口還能連接,但服務沒法提供了,這時我們需要語義級的探活。
根據提供者提供的服務和配置發起一個請求,如果返回和預期相符合,則判定為服務存活。
我們通常將這個探活留出擴展點,一般可以擴展出HTTP、MySQL、Redis、Thrift等協議的語義探活,以HTTP為例,服務提供方配置探活的URI,注冊中心把提供方的ip、port與URI進行拼接、發起請求,如果響應符合預期(如返回碼為2xx),則這次探活成功,同理,也可擴展出其他協議的語義級探活。
探活兜底
探活雖好,但有時候又很危險,如果注冊中心與提供者的網絡閃斷,則可能將提供者全部摘除,這是個非常危險的操作,為了防止這種情況,探活兜底是很有必要的一種行為,比如同一個服務集群不能摘除超過1/3,當然這個比例是個經驗值,也最好可以配置化。
生態建設
優雅發布
優雅發布包括優雅退出和優雅上線,優雅是指在應用退出和上線過程中沒有報錯。
注冊中心結合發布系統來做優雅發布是最好的搭配。發布系統在停止應用前,向注冊中心發起禁用請求(停止接流),注銷后再停止應用,服務上線后啟動完成后,再將服務開啟,接受流量。
框架適配
一個注冊中心如果想要更多的人來使用,則需要適配各種主流開發語言如Go/Java/Cpp等,適配一些主流框架如Dubbo/SpringCloud/gRPC等,這樣用戶用起來才更加方便,缺點是維護成本變高。
DNS 服務發現
對于無法接入服務發現SDK的用戶,如果也想享受服務發現能力,怎么做呢?
業界有一種做法是自定義一個DNS攔截器,將DNS請求攔截,通過域名(對應到服務名)去注冊中心找提供者。但這樣做有一個缺點是DNS只能發現ip,端口沒法自動發現。
一般這種攔截器可通過中心的DNS服務器或者本地的DNS agent代理來實現,也可以自定義編程語言的DNS解析插件來實現,像Go/Java都可以自定義DNS解析插件,但這種就屬于入侵比較強了。