另外有一部分服務(wù)則通過手動添加的方式來注冊。這一部分主要是用到的一些開源軟件,修改他們的成本比較高,索性就不改,采用手動添加就好了(這就是偷懶 ^_^)。而這部分服務(wù)占比很小,所以手動的成本也不高。
B 、服務(wù)可用性如何保證?
那既然 Naming-Service 承擔(dān)了服務(wù)注冊和獲取的責(zé)任,那么服務(wù)的可用性如何保證呢?老王設(shè)計的時候, Naming-Service 專門有一個服務(wù)功能:健康檢查。 Naming-Service 會定期的檢查服務(wù)是否存活(主要是 socket 的可連接性),以及是否可以提供服務(wù)( ping 檢查 - 這個老王偷懶了沒做 ~ ),這個是配置的,一般是秒級(因為調(diào)用者一般都是有重試,所以這個時間差還是可以接受的)。如果健康檢查多次以后,服務(wù)仍然不可用,則出現(xiàn)服務(wù)報警,同時, Naming-Service 會將出問題的機器從可用服務(wù)列表中摘除。這樣保證服務(wù)列表在絕大多數(shù)情況下都是可用的。
C 、單點如何解決?
從之前的拓撲圖可以看到,我們的 Naming-Service 是星形結(jié)構(gòu)的中心結(jié)點。如果這個服務(wù)掛掉了,我們的整個系統(tǒng)就癱瘓了,對吧。那我們?nèi)绾谓鉀Q這個中心結(jié)點的單點問題呢?
老王用了幾個手段:
a 、服務(wù)的多機化 + 存儲的主從化:

Naming-Service 提供一個服務(wù)組(多個 IP 配置到服務(wù)列表中),如果某一臺掛掉了,請求服務(wù)可以重試其他 Naming-Service 。
同時,后臺的數(shù)據(jù)存儲用的是數(shù)據(jù)庫主從的方式,即使有庫掛掉了,也還有其他備份庫可以使用。
b 、定期重復(fù)注冊。
剛剛將注冊方式的時候,也講到這個問題。即使所有數(shù)據(jù)庫都掛掉了(比如:機房光纖挖斷了),那我能夠很快的搭建好另外一個數(shù)據(jù)庫,通過定期重復(fù)注冊的方式,迅速恢復(fù)服務(wù)。
c 、本地備份 service-list 。
在客戶端有一個功能,就是請求完 Naming-Service 以后,會在本地生成一份最新請求下來的服務(wù)列表(自動的)。如果我們的 Naming-Service 遭到毀滅性打擊(比如:所在的機房斷電了),我們本地還有一份最近的服務(wù)列表,可以直接使用。
通過上述幾種方式,基本上能保證我們服務(wù)不會出現(xiàn)問題。
其實還有另外一些實現(xiàn)方式:比如 Naming-Service 之間通過一些廣播協(xié)議(比如:gossip 等)將注冊信息進行廣播,各自存儲一份信息,而不采用數(shù)據(jù)庫集群的方式。也可以讓客戶端向所有的 Naming-Service 廣播自己的注冊信息,而每個 Naming-Service 也是獨自保留自己的信息等等方式。
3 、應(yīng)用場景
Naming-Service 在幾百臺、幾千臺機器的體系架構(gòu)中其實是蠻好的一個解決方案。如果再大規(guī)模,如幾萬、十幾萬臺機器的規(guī)模下是否適合,老王就不得而知了(因為沒有那么多機器去實驗,不過老王覺得其實也可以通過拆分系統(tǒng),化整為零來解決)。
不過現(xiàn)在也有很多系統(tǒng),使用了去中心化的設(shè)計思想。比如: memcache 就是通過客戶端做一致 hash 的方式,來避免中心化的結(jié)點。 redis 好像有自己的一套分布式去中心化的方案。這些方案都是可行的。
在分布式體系架構(gòu)中,沒有一種最完美的方案,只有更適合自己的方案。所以,今天老王拋了一種方案給大家,供大家在平時工作中來選擇。