源码 状态机_[源码阅读] 阿里SOFA服务注册中心MetaServer(1)
[源碼閱讀] 阿里SOFA服務(wù)注冊中心MetaServer(1)
0x00 摘要
0x01 服務(wù)注冊中心
1.1 服務(wù)注冊中心簡介
1.2 SOFARegistry 總體架構(gòu)
1.3 為什么要分層
0x02 MetaServer
2.1簡介
2.2 問題
0x03 代碼結(jié)構(gòu)
0x04 啟動運(yùn)行
4.1 集成部署
4.2 獨立部署
0x05 總體邏輯
5.1 程序主體
5.2 配置
0x06 啟動
6.1 架構(gòu)
6.2 類定義
6.3 通信 Exchange
6.4 啟動入口
6.4.1 啟動服務(wù)Server
6.4.2 ExecutorManager
6.4.3 ServiceFactory
0xFF 參考
0x00 摘要
SOFARegistry 是螞蟻金服開源的一個生產(chǎn)級、高時效、高可用的服務(wù)注冊中心。本系列將帶領(lǐng)大家一起分析其MetaServer的實現(xiàn)機(jī)制,本文為第一篇,介紹MetaServer總體架構(gòu)。
本系列總體參考了官方的博客,具體請參見"0xFF 參考"。大家可以把參考作為總綱,我這系列文章作為注釋補(bǔ)遺翻閱。
0x01 服務(wù)注冊中心
1.1 服務(wù)注冊中心簡介
在微服務(wù)架構(gòu)下,一個互聯(lián)網(wǎng)應(yīng)用的服務(wù)端背后往往存在大量服務(wù)間的相互調(diào)用。例如服務(wù) A 在鏈路上依賴于服務(wù) B,那么在業(yè)務(wù)發(fā)生時,服務(wù) A 需要知道服務(wù) B 的地址,才能完成服務(wù)調(diào)用。而分布式架構(gòu)下,每個服務(wù)往往都是集群部署的,集群中的機(jī)器也是經(jīng)常變化的,所以服務(wù) B 的地址不是固定不變的。如果要保證業(yè)務(wù)的可靠性,服務(wù)調(diào)用者則需要感知被調(diào)用服務(wù)的地址變化。
既然成千上萬的服務(wù)調(diào)用者都要感知這樣的變化,那這種感知能力便下沉成為微服務(wù)中一種固定的架構(gòu)模式:服務(wù)注冊中心。
服務(wù)注冊中心里,有服務(wù)提供者和服務(wù)消費(fèi)者兩種重要的角色,服務(wù)調(diào)用方是消費(fèi)者,服務(wù)被調(diào)方是提供者。對于同一臺機(jī)器,往往兼具兩者角色,既被其它服務(wù)調(diào)用,也調(diào)用其它服務(wù)。服務(wù)提供者將自身提供的服務(wù)信息發(fā)布到服務(wù)注冊中心,服務(wù)消費(fèi)者通過訂閱的方式感知所依賴服務(wù)的信息是否發(fā)生變化。
服務(wù)注冊中心在服務(wù)調(diào)用的場景中,扮演一個“中介”的角色,服務(wù)發(fā)布者 (Publisher) 將服務(wù)發(fā)布到服務(wù)注冊中心,服務(wù)調(diào)用方 (Subscriber) 通過訪問服務(wù)注冊中心就能夠獲取到服務(wù)信息,進(jìn)而實現(xiàn)調(diào)用。
Subscriber 在第一次調(diào)用服務(wù)時,會通過 Registry 找到相應(yīng)的服務(wù)的 IP 地址列表,通過負(fù)載均衡算法從 IP 列表中取一個服務(wù)提供者的服務(wù)器調(diào)用服務(wù)。同時 Subscriber 會將 Publisher 的服務(wù)列表數(shù)據(jù)緩存到本地,供后續(xù)使用。當(dāng) Subscriber 后續(xù)再調(diào)用 Publisher 時,優(yōu)先使用緩存的地址列表,不需要再去請求Registry。
+----------+????????????????????????????????????+---------+|Subscriber|?+----------+??????????|??????????????|??????????+---------+
??????????????????????|??????????????|
+----------+??????????|??????????????v
|Subscriber|?+----------+????????????????????????????????|???+----------++?????????+---------+
+----------+??????????|??????????????^
|Subscriber|?+----------+?????????????????????????|
?????????????????????????????????????|??????????+---------+
?????????????????????????????????????+----------+Publisher|
????????????????????????????????????????????????+---------+
服務(wù)注冊中心Registry的最主要能力是服務(wù)注冊和服務(wù)發(fā)現(xiàn)兩個過程。
- 服務(wù)注冊的過程最重要是對服務(wù)發(fā)布的信息進(jìn)行存儲。
- 服務(wù)發(fā)現(xiàn)的過程是把服務(wù)發(fā)布端的所有變化(包括節(jié)點變化和服務(wù)信息變化)及時準(zhǔn)確的通知到訂閱方的過程。
1.2 SOFARegistry 總體架構(gòu)
1.2.1 分層
SOFARegistry 作為服務(wù)注冊中心,分為4個層,分別為:
- Client 層
Client 層是應(yīng)用服務(wù)器集群。Client 層是應(yīng)用層,每個應(yīng)用系統(tǒng)通過依賴注冊中心相關(guān)的客戶端 jar 包,通過編程方式來使用服務(wù)注冊中心的服務(wù)發(fā)布和服務(wù)訂閱能力。
- Session 層
Session層是服務(wù)器集群。顧名思義,Session 層是會話層,通過長連接和 Client 層的應(yīng)用服務(wù)器保持通訊,負(fù)責(zé)接收 Client 的服務(wù)發(fā)布和服務(wù)訂閱請求。
在服務(wù)注冊中心的服務(wù)端因為每個存儲節(jié)點對應(yīng)的客戶端的鏈接數(shù)據(jù)量有限,必須進(jìn)行特殊的一層劃分用于專門收斂無限擴(kuò)充的客戶端連接,然后在透傳相應(yīng)的請求到存儲層。
該層只在內(nèi)存中保存各個服務(wù)的發(fā)布訂閱關(guān)系,對于具體的服務(wù)信息,只在 Client 層和 Data 層之間透傳轉(zhuǎn)發(fā)。Session 層是一個無數(shù)據(jù)狀態(tài)的代理層,可以隨著 Client 層應(yīng)用規(guī)模的增長而擴(kuò)容。
因為 SOFARegistry 的服務(wù)發(fā)現(xiàn)需要較高的時效性,對外表現(xiàn)為主動推送變更到客戶端,所以推送的主體實現(xiàn)也集中在 Session 層,內(nèi)部的推拉結(jié)合主要是通過 Data 存儲層的數(shù)據(jù)版本變更推送到所有 Session 節(jié)點,各個 Session 節(jié)點根據(jù)存儲的訂閱關(guān)系和首次訂閱獲取的數(shù)據(jù)版本信息進(jìn)行比對,最終確定推送給那些服務(wù)消費(fèi)方客戶端。
- Data 層
數(shù)據(jù)服務(wù)器集群。Data 層通過分片存儲的方式保存著所用應(yīng)用的服務(wù)注冊數(shù)據(jù)。數(shù)據(jù)按照 dataInfoId(每一份服務(wù)數(shù)據(jù)的唯一標(biāo)識)進(jìn)行一致性 Hash 分片,多副本備份,保證數(shù)據(jù)的高可用。Data 層可以隨著數(shù)據(jù)規(guī)模的增長,在不影響業(yè)務(wù)的前提下實現(xiàn)平滑的擴(kuò)縮容。
- Meta 層
元數(shù)據(jù)服務(wù)器集群。這個集群管轄的范圍是 Session 服務(wù)器集群和 Data 服務(wù)器集群的服務(wù)器信息,其角色就相當(dāng)于 SOFARegistry 架構(gòu)內(nèi)部的服務(wù)注冊中心,只不過 SOFARegistry 作為服務(wù)注冊中心是服務(wù)于廣大應(yīng)用服務(wù)層,而 Meta 集群是服務(wù)于 SOFARegistry 內(nèi)部的 Session 集群和 Data 集群,Meta 層能夠感知到 Session 節(jié)點和 Data 節(jié)點的變化,并通知集群的其它節(jié)點。
1.3 為什么要分層
SOFARegistry 內(nèi)部為什么要進(jìn)行數(shù)據(jù)分層,是因為系統(tǒng)容量的限制。
在 SOFARegistry 的應(yīng)用場景中,體量龐大的數(shù)據(jù)主要有兩類:Session 數(shù)據(jù)、服務(wù)信息數(shù)據(jù)。兩類數(shù)據(jù)的相同之處在于其數(shù)據(jù)量都會不斷擴(kuò)展,而不同的是其擴(kuò)展的原因并不相同:
- Session 是對應(yīng)于 Client 的連接,其數(shù)據(jù)量是隨著業(yè)務(wù)機(jī)器規(guī)模的擴(kuò)展而增長,
- 服務(wù)信息數(shù)據(jù)量的增長是由 Publisher 的發(fā)布所決定。
所以 SOFARegistry 通過分層設(shè)計,將兩種數(shù)據(jù)隔離,從而使二者的擴(kuò)容互不影響。
圖3 - 分層,擴(kuò)容互不影響這也是 SOFARegistry 設(shè)計三層模型的原因,通過 SessionServer 來負(fù)責(zé)與 Client 的連接,將每個 Client 的連接數(shù)收斂到 1,這樣當(dāng) Client 數(shù)量增長時,只需要擴(kuò)容 SessionServer 集群就可以了。所以從設(shè)計初衷上我們就能夠看出來 SessionServer 必須要滿足的兩個主要能力:從 DataServer 獲取服務(wù)信息數(shù)據(jù);以及保存與 Client 的會話。
0x02 MetaServer
2.1簡介
MetaServer 在 SOFARegistry 中,承擔(dān)著集群元數(shù)據(jù)管理的角色,用來維護(hù)集群成員列表,可以認(rèn)為是 SOFARegistry 注冊中心的注冊中心。
MetaServer 作為 SOFARegistry 的元數(shù)據(jù)中心,其核心功能可以概括為:集群成員列表管理。比如:
- 節(jié)點列表的注冊與存儲
- 節(jié)點列表的變更通知
- 節(jié)點健康監(jiān)測
當(dāng) SessionServer 和 DataServer 需要知道集群列表,并且需要擴(kuò)縮容時,MetaServer 將會提供相應(yīng)的數(shù)據(jù)。
其內(nèi)部架構(gòu)如下圖所示:
內(nèi)部架構(gòu)圖MetaServer 基于 Bolt, 通過 TCP 私有協(xié)議的形式對外提供服務(wù),包括 DataServer, SessionServer 等,處理節(jié)點的注冊,續(xù)約和列表查詢等請求。
同時也基于 Http 協(xié)議提供控制接口,比如可以控制 session 節(jié)點是否開啟變更通知, 健康檢查接口等。
成員列表數(shù)據(jù)存儲在 Repository 中,Repository 被一致性協(xié)議層進(jìn)行包裝,作為 SOFAJRaft 的狀態(tài)機(jī)實現(xiàn),所有對 Repository 的操作都會同步到其他節(jié)點, 通過Rgistry來操作存儲層。
MetaServer 使用 Raft 協(xié)議保證高可用和數(shù)據(jù)一致性, 同時也會保持與注冊的節(jié)點的心跳,對于心跳超時沒有續(xù)約的節(jié)點進(jìn)行驅(qū)逐,來保證數(shù)據(jù)的有效性。
在可用性方面,只要未超過半數(shù)節(jié)點掛掉,集群都可以正常對外提供服務(wù),半數(shù)以上掛掉,Raft 協(xié)議無法選主和日志復(fù)制,因此無法保證注冊的成員數(shù)據(jù)的一致性和有效性。整個集群不可用 不會影響 Data 和 Session 節(jié)點的正常功能,只是無法感知節(jié)點列表變化。
2.2 問題
空談無用,just show the code。于是讓我們帶著問題來思考,即從宏觀和微觀角度來思考MetaServer應(yīng)該實現(xiàn)什么功能,具體是怎么實現(xiàn)的。
思考:
- MetaServer具體是以什么方式實現(xiàn)。
- MetaServer如何實現(xiàn)高可用。
- MetaServer如何實現(xiàn)或者應(yīng)用內(nèi)部通訊協(xié)議。
- MetaServer如何保持DataNode列表和SessionNode列表。
- MetaServer如何處理節(jié)點列表變更推送。
- MetaServer如何處理節(jié)點列表查詢。
- MetaServer如何處理MetaServer如何保證數(shù)據(jù)一致性。
- 各個集群是如何搭建,如何完成高可用。
下面我們就一一分析。
0x03 代碼結(jié)構(gòu)
我們在 sofa-registry-5.4.2/server/server/meta/src/main/java/com/alipay/sofa/registry/server/meta 看看目錄和文件結(jié)構(gòu)。
按照目錄我們可以大致了解功能
- MetaApplication.java :MetaServer程序主體,入口。
- bootstrap :負(fù)責(zé)MetaServer的啟動和配置。
- executor :負(fù)責(zé)各種定時管理任務(wù),他的啟動設(shè)置是在 MetaServerBootstrap.initRaft ?之中。
- listener ?:SOFARegistry 采用了 Handler - Task & Strategy - Listener 的方式來應(yīng)對服務(wù)注冊中的各種場景和任務(wù),這樣的處理模型能夠盡可能的讓代碼和架構(gòu)清晰整潔。
- node :對業(yè)務(wù)節(jié)點的抽象,包括DataNode,SessionNode,MetaNode。
- registry :通過Registry來操作存儲層,所有對 Repository 的操作都會同步到其他節(jié)點。
- remoting :對外交互接口,提供各種對外的 handler。
- repository :集群節(jié)點列表存儲在 Repository 中,通過 Raft 強(qiáng)一致性協(xié)議對外提供節(jié)點注冊、續(xù)約、列表查詢等 Bolt 請求,從而保障集群獲得的數(shù)據(jù)是強(qiáng)一致性的。Repository 被一致性協(xié)議層進(jìn)行包裝,作為 SOFAJRaft 的狀態(tài)機(jī)實現(xiàn)。
- resource :http Server的接口,用來響應(yīng)控制消息。
- store :封裝了存儲節(jié)點的操作。
- task :封裝了異步執(zhí)行邏輯,通過TaskDispatcher,TaskExecutors 來執(zhí)行各種定義好的異步Task。
具體代碼結(jié)構(gòu)如下:
.├──?MetaApplication.java
├──?bootstrap
│???├──?AbstractNodeConfigBean.java
│???├──?EnableMetaServer.java
│???├──?MetaServerBootstrap.java
│???├──?MetaServerConfig.java
│???├──?MetaServerConfigBean.java
│???├──?MetaServerConfiguration.java
│???├──?MetaServerInitializerConfiguration.java
│???├──?NodeConfig.java
│???├──?NodeConfigBeanProperty.java
│???└──?ServiceFactory.java
├──?executor
│???└──?ExecutorManager.java
├──?listener
│???├──?DataNodeChangePushTaskListener.java
│???├──?PersistenceDataChangeNotifyTaskListener.java
│???├──?ReceiveStatusConfirmNotifyTaskListener.java
│???└──?SessionNodeChangePushTaskListener.java
├──?node
│???├──?DataNodeService.java
│???├──?MetaNodeService.java
│???├──?NodeOperator.java
│???├──?NodeService.java
│???├──?SessionNodeService.java
│???└──?impl
│???????├──?DataNodeServiceImpl.java
│???????├──?MetaNodeServiceImpl.java
│???????└──?SessionNodeServiceImpl.java
├──?registry
│???├──?MetaServerRegistry.java
│???└──?Registry.java
├──?remoting
│???├──?DataNodeExchanger.java
│???├──?MetaClientExchanger.java
│???├──?MetaServerExchanger.java
│???├──?RaftExchanger.java
│???├──?SessionNodeExchanger.java
│???├──?connection
│???│???├──?DataConnectionHandler.java
│???│???├──?MetaConnectionHandler.java
│???│???├──?NodeConnectManager.java
│???│???└──?SessionConnectionHandler.java
│???└──?handler
│???????├──?AbstractServerHandler.java
│???????├──?DataNodeHandler.java
│???????├──?FetchProvideDataRequestHandler.java
│???????├──?GetNodesRequestHandler.java
│???????├──?RenewNodesRequestHandler.java
│???????└──?SessionNodeHandler.java
├──?repository
│???├──?NodeConfirmStatusService.java
│???├──?NodeRepository.java
│???├──?RepositoryService.java
│???├──?VersionRepositoryService.java
│???├──?annotation
│???│???└──?RaftAnnotationBeanPostProcessor.java
│???└──?service
│???????├──?DataConfirmStatusService.java
│???????├──?DataRepositoryService.java
│???????├──?MetaRepositoryService.java
│???????├──?SessionConfirmStatusService.java
│???????├──?SessionRepositoryService.java
│???????└──?SessionVersionRepositoryService.java
├──?resource
│???├──?BlacklistDataResource.java
│???├──?DecisionModeResource.java
│???├──?HealthResource.java
│???├──?MetaDigestResource.java
│???├──?MetaStoreResource.java
│???├──?PersistentDataResource.java
│???├──?RenewSwitchResource.java
│???└──?StopPushDataResource.java
├──?store
│???├──?DataStoreService.java
│???├──?MetaStoreService.java
│???├──?RenewDecorate.java
│???├──?SessionStoreService.java
│???└──?StoreService.java
└──?task
????├──?AbstractMetaServerTask.java
????├──?Constant.java
????├──?DataNodeChangePushTask.java
????├──?MetaServerTask.java
????├──?PersistenceDataChangeNotifyTask.java
????├──?ReceiveStatusConfirmNotifyTask.java
????├──?SessionNodeChangePushTask.java
????└──?processor
????????├──?DataNodeSingleTaskProcessor.java
????????├──?MetaNodeSingleTaskProcessor.java
????????└──?SessionNodeSingleTaskProcessor.java
16?directories,?75?files
0x04 啟動運(yùn)行
啟動可以參考 ?https://www.sofastack.tech/projects/sofa-registry/server-quick-start/
SOFARegistry 支持兩種部署模式,分別是集成部署模式及獨立部署模式。
4.1 集成部署
4.1.1 Linux/Unix/Mac
啟動命令:sh bin/startup.sh
4.1.2 Windows
雙擊 bin 目錄下的 startup.bat 運(yùn)行文件。
4.1.3 啟動信息
通過下列l(wèi)og我們可以看到啟動信息。
MetaApplication
[2020-09-12?20:23:05,463][INFO][main][MetaServerBootstrap]?-?Open?meta?server?port?9612?success![2020-09-12?20:23:08,198][INFO][main][MetaServerBootstrap]?-?Open?http?server?port?9615?success!
[2020-09-12?20:23:10,298][INFO][main][MetaServerBootstrap]?-?Raft?server?port?9614?start?success!group?RegistryGroup
[2020-09-12?20:23:10,322][INFO][main][MetaServerInitializerConfiguration]?-?Started?MetaServer
DataApplication
[2020-09-12?20:23:25,004][INFO][main][DataServerBootstrap]?-?Open?http?server?port?9622?success![2020-09-12?20:23:26,084][INFO][main][DataServerBootstrap]?-?start?server?success
[2020-09-12?20:23:26,094][INFO][main][DataApplication]?-?Started?DataApplication?in?10.217?seconds?(JVM?running?for?11.316)
SessionApplication
[2020-09-12?20:23:50,243][INFO][main][SessionServerBootstrap]?-?Open?http?server?port?9603?success![2020-09-12?20:23:50,464][INFO][main][SessionServerInitializer]?-?Started?SessionServer
[2020-09-12?20:23:50,526][INFO][main][SessionApplication]?-?Started?SessionApplication?in?12.516?seconds?(JVM?running?for?13.783)
各個 Server 的默認(rèn)端口分別為:
meta.server.sessionServerPort=9610meta.server.dataServerPort=9611
meta.server.metaServerPort=9612
meta.server.raftServerPort=9614
meta.server.httpServerPort=9615
可訪問三個角色提供的健康監(jiān)測 API,或查看日志 logs/registry-startup.log:
#?查看meta角色的健康檢測接口:$?curl?http://localhost:9615/health/check
{"success":true,"message":"...?raftStatus:Leader"}
#?查看data角色的健康檢測接口:
$?curl?http://localhost:9622/health/check
{"success":true,"message":"...?status:WORKING"}
#?查看session角色的健康檢測接口:
$?curl?http://localhost:9603/health/check
{"success":true,"message":"..."}
4.2 獨立部署
在這里我們可以看出來各種集群是如何搭建,以及如何在集群內(nèi)部通訊,分布式協(xié)調(diào)。
按照常理來說,每個集群都應(yīng)該依賴zookeeper之類的軟件來進(jìn)行自己內(nèi)部的協(xié)調(diào),比如統(tǒng)一命名服務(wù)、狀態(tài)同步服務(wù)、集群管理、分布式應(yīng)用配置項。但實際上我們沒有發(fā)現(xiàn)類似的使用。
具體看配置文件發(fā)現(xiàn),每臺機(jī)器都要設(shè)置所有的metaServer的host。這說明Data Server, ?Session Server則強(qiáng)依賴Meta Server。
實際上,MetaServer 使用 Raft 協(xié)議保證高可用和數(shù)據(jù)一致性, 同時也會保持與注冊的節(jié)點的心跳,對于心跳超時沒有續(xù)約的節(jié)點進(jìn)行驅(qū)逐,來保證數(shù)據(jù)的有效性。Meta 層能夠感知到 Session 節(jié)點和 Data 節(jié)點的變化,并通知集群的其它節(jié)點。
這就涉及到各個角色的 failover 機(jī)制:
- MetaServer 集群部署,內(nèi)部基于 Raft 協(xié)議選舉和復(fù)制,只要不超過 1?2 節(jié)點宕機(jī),就可以對外服務(wù)。
- DataServer 集群部署,基于一致性 Hash 承擔(dān)不同的數(shù)據(jù)分片,數(shù)據(jù)分片擁有多個副本,一個主副本和多個備副本。如果 DataServer 宕機(jī),MetaServer 能感知,并通知所有 DataServer 和 SessionServer,數(shù)據(jù)分片可 failover 到其他副本,同時 DataServer 集群內(nèi)部會進(jìn)行分片數(shù)據(jù)的遷移。
- SessionServer 集群部署,任何一臺 SessionServer 宕機(jī)時 Client 會自動 failover 到其他 SessionServer,并且 Client 會拿到最新的 SessionServer 列表,后續(xù)不會再連接這臺宕機(jī)的 SessionServer。
4.2.1 部署meta
每臺機(jī)器在部署時需要修改 conf/application.properties 配置:
#?將3臺meta機(jī)器的ip或hostname配置到下方(填入的hostname會被內(nèi)部解析為ip地址)nodes.metaNode=DefaultDataCenter:,,
nodes.localDataCenter=DefaultDataCenter
4.2.2 部署data
每臺機(jī)器在部署時需要修改 conf/application.properties 配置:
#?將3臺?meta?機(jī)器的?ip?或?hostname?配置到下方(填入的?hostname?會被內(nèi)部解析為?ip?地址)nodes.metaNode=DefaultDataCenter:,,
nodes.localDataCenter=DefaultDataCenter
data.server.numberOfReplicas=1000
4.2.3 部署 session
每臺機(jī)器在部署時需要修改 conf/application.properties 配置:
#?將3臺?meta?機(jī)器的?ip?或?hostname?配置到下方(填入的?hostname?會被內(nèi)部解析為?ip?地址)nodes.metaNode=DefaultDataCenter:,,
nodes.localDataCenter=DefaultDataCenter
nodes.localRegion=DefaultZone
0x05 總體邏輯
MetaServer 在啟動時,會啟動三個 Bolt Server,并且注冊 Processor Handler,處理對應(yīng)的請求:
- DataServer:處理 DataNode 相關(guān)的請求;
- SessionServer:處理 SessionNode 相關(guān)的請求;
- MetaServer:處理MetaNode相關(guān)的請求;
然后啟動 HttpServer, 用于處理 Admin 請求,提供推送開關(guān),集群數(shù)據(jù)查詢等 Http 接口。
最后啟動 Raft 服務(wù), 每個節(jié)點同時作為 RaftClient 和 RaftServer, 用于集群間的變更和數(shù)據(jù)同步。
5.1 程序主體
MetaServer 是一個SpringBootApplication,主要起作用的就是EnableMetaServer。
@EnableMetaServer@SpringBootApplication
public?class?MetaApplication?{
????public?static?void?main(String[]?args)?{
????????SpringApplication.run(MetaApplication.class,?args);
????}
}
具體參見下圖
+-------------------+|?@EnableMetaServer?|
|???????????????????|
|??MetaApplication??|
+-------------------+
EnableMetaServer注解引入了MetaServerConfiguration
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MetaServerConfiguration.class)
public?@interface?EnableMetaServer?{
}
MetaServerConfiguration是各種配置,并且引入 MetaServerInitializerConfiguration負(fù)責(zé)啟動。
@Configuration@Import(MetaServerInitializerConfiguration.class)
@EnableConfigurationProperties
public?class?MetaServerConfiguration?{
}
所以我們可以知道:
- MetaServerConfiguration :負(fù)責(zé)配置
- MetaServerInitializerConfiguration :負(fù)責(zé)啟動
于是程序總結(jié)結(jié)構(gòu)演化為下圖:
???????????????????????????????????(Init)????????????????????????????+------------------------------------+
????????????????????????????|?MetaServerInitializerConfiguration?|
????????????????????????????+-------------+----------------------+
??????????????????????????????????????????^
+-------------------+?????????????????????|
|?@EnableMetaServer?|?????????????????????|
|???????????????????|?????????????????????|
|??MetaApplication??|?????????????????????|
+-------------+-----+?????????????????????|?(Configuration)
??????????????|?????????????????+---------+---------------+
??????????????+-------------->??|?MetaServerConfiguration?|
????????????????????????????????+-------------------------+
下面我們開始引入配置。
5.2 配置
MetaServer 模塊的各個 bean 在 JavaConfig 中統(tǒng)一配置,JavaConfig 類為 MetaServerConfiguration。
5.2.1 配置分類
MetaServerConfiguration 具體有以下幾類配置:
- Bootstrap,負(fù)責(zé)MetaServer啟動配置,是核心啟動類。
- ServerConfig,負(fù)責(zé)MetaServer的配置項,比如MetaServerConfig,NodeConfig,PropertySplitter。
- ServerServiceConfiguration,負(fù)責(zé)服務(wù)相關(guān)的配置,比如 sessionNodeService,storeServiceFactory,sessionStoreService。
- ServerRepositoryConfiguration,負(fù)責(zé)Repository相關(guān)的配置,比如dataRepositoryService,sessionRepositoryService等。
- ServerRemotingConfiguration,負(fù)責(zé)網(wǎng)絡(luò)相關(guān)配置,比如BoltExchange,JerseyExchange,這里隨后會重點說明。
- ResourceConfiguration,負(fù)責(zé)Resource相關(guān)配置,比如 jerseyResourceConfig,persistentDataResource。
- ServerTaskConfiguration,負(fù)責(zé)各種 ?task 相關(guān)配置 ,比如dataNodeSingleTaskProcessor。
- ExecutorConfiguation,ExecutorManager相關(guān)配置。
- MetaDBConfiguration,DB相關(guān)配置。
具體縮略版代碼如下 :
@Configuration@Import(MetaServerInitializerConfiguration.class)
@EnableConfigurationProperties
public?class?MetaServerConfiguration?{
????@Bean
????@ConditionalOnMissingBean
????public?MetaServerBootstrap?metaServerBootstrap()?{
????}
????@Configuration
????protected?static?class?MetaServerConfigBeanConfiguration?{
????}
????@Configuration
????public?static?class?MetaServerServiceConfiguration?{
????}
????@Configuration
????public?static?class?MetaServerRepositoryConfiguration?{
????}
????@Configuration
????public?static?class?MetaServerRemotingConfiguration?{
????}
????@Configuration
????public?static?class?ResourceConfiguration?{
????}
????@Configuration
????public?static?class?MetaServerTaskConfiguration?{
????}
????@Configuration
????public?static?class?ExecutorConfiguation?{
????}
????@Configuration
????public?static?class?MetaDBConfiguration?{
????}??
}
我們的圖進(jìn)化如下:
???????????????????????????????????(Init)????????????????????????????+------------------------------------+
????????????????????????????|?MetaServerInitializerConfiguration?|
????????????????????????????+-------------+----------------------+??????+---------------------+
??????????????????????????????????????????^???????????????????????+-->??|?MetaServerBootstrap?|
+-------------------+?????????????????????|???????????????????????|?????+---------------------+
|?@EnableMetaServer?|?????????????????????|???????????????????????|?????+---------------------------------+
|???????????????????|?????????????????????|???????????????????????+-->??|MetaServerConfigBeanConfiguration|
|??MetaApplication??|?????????????????????|???????????????????????|?????+---------------------------------+
+--------------+----+?????????????????????|???????????????????????|?????+------------------------------+
???????????????|??????????????????????????|???????????????????????+-->??|MetaServerServiceConfiguration|
???????????????|??????????????????????????|???????????????????????|?????+------------------------------+
???????????????|??????????????????????????|???????????????????????|?????+---------------------------------+
???????????????|??????????????????????????|???????????????????????+-->??|MetaServerRepositoryConfiguration|
???????????????|??????????????????????????|???????????????????????|?????+---------------------------------+
???????????????|??????????????????????????|?(Configuration)???????|?????+-------------------------------+
???????????????|????????????????+---------+---------------+???????+-->??|MetaServerRemotingConfiguration|
???????????????+-------------->?|?MetaServerConfiguration?|?+-----+?????+-------------------------------+
????????????????????????????????+-------------------------+???????|?????+----------------------+
??????????????????????????????????????????????????????????????????+-->??|ResourceConfiguration?|
??????????????????????????????????????????????????????????????????|?????+----------------------+
??????????????????????????????????????????????????????????????????|?????+---------------------------+
??????????????????????????????????????????????????????????????????+-->??|MetaServerTaskConfiguration|
??????????????????????????????????????????????????????????????????|?????+---------------------------+
??????????????????????????????????????????????????????????????????|?????+---------------------+
??????????????????????????????????????????????????????????????????+-->??|ExecutorConfiguation?|
??????????????????????????????????????????????????????????????????|?????+---------------------+
??????????????????????????????????????????????????????????????????|?????+--------------------+
??????????????????????????????????????????????????????????????????+-->??|MetaDBConfiguration?|
????????????????????????????????????????????????????????????????????????+--------------------+
下圖為了手機(jī)閱讀
5.2.2 handler的配置
這里要特殊提一下handler的配置,因為這是后續(xù)分析的主體之一,是三個 Bolt Server的handler。
@Configurationpublic?static?class?MetaServerRemotingConfiguration?{
????@Bean
????public?Exchange?boltExchange()?{
????????return?new?BoltExchange();
????}
????@Bean
????public?Exchange?jerseyExchange()?{
????????return?new?JerseyExchange();
????}
????@Bean(name?=?"sessionServerHandlers")
????public?Collection?sessionServerHandlers()?{
????????Collection?list?=?new?ArrayList<>();
????????list.add(sessionConnectionHandler());
????????list.add(sessionNodeHandler());
????????list.add(renewNodesRequestHandler());
????????list.add(getNodesRequestHandler());
????????list.add(fetchProvideDataRequestHandler());return?list;
????}@Bean(name?=?"dataServerHandlers")public?Collection?dataServerHandlers()?{
????????Collection?list?=?new?ArrayList<>();
????????list.add(dataConnectionHandler());
????????list.add(getNodesRequestHandler());
????????list.add(dataNodeHandler());
????????list.add(renewNodesRequestHandler());
????????list.add(fetchProvideDataRequestHandler());return?list;
????}@Bean(name?=?"metaServerHandlers")public?Collection?metaServerHandlers()?{
????????Collection?list?=?new?ArrayList<>();
????????list.add(metaConnectionHandler());
????????list.add(getNodesRequestHandler());return?list;
????}
}
于是我們的總體架構(gòu)進(jìn)化具體見下圖
???????????????????????????????(Init)????????????????????????+------------------------------------+
????????????????????????|?MetaServerInitializerConfiguration?|
????????????????????????+--------------+---------------------+
???????????????????????????????????????^
???????????????????????????????????????|
???????????????????????????????????????|
???????????????????????????????????????|
???????????????????????????????????????|
???????????????????????????????????????|?????????????????????????????+---------------------+
???????????????????????????????????????|???????????????????????+-->??|?MetaServerBootstrap?|
+-------------------+??????????????????|???????????????????????|?????+---------------------+
|?@EnableMetaServer?|??????????????????|???????????????????????|?????+---------------------------------+
|???????????????????|??????????????????|???????????????????????+-->??|MetaServerConfigBeanConfiguration|
|??MetaApplication??|??????????????????|???????????????????????|?????+---------------------------------+
+--------------+----+??????????????????|???????????????????????|?????+------------------------------+?????????????+-----------------------+
???????????????|???????????????????????|???????????????????????+-->??|MetaServerServiceConfiguration|??????+--->??|?sessionServerHandlers?|
???????????????|???????????????????????|???????????????????????|?????+------------------------------+??????|??????+-----------------------+
???????????????|???????????????????????|???????????????????????|?????+---------------------------------+???|??????+--------------------+
???????????????|???????????????????????|???????????????????????+-->??|MetaServerRepositoryConfiguration+------->??|?dataServerHandlers?|
???????????????|???????????????????????|???????????????????????|?????+---------------------------------+???|??????+--------------------+
???????????????|???????????????????????|?(Configuration)???????|?????+-------------------------------+?????|??????+--------------------+
???????????????|?????????????+---------+---------------+???????+-->??|MetaServerRemotingConfiguration|?????+--->??|?metaServerHandlers?|
???????????????+----------->?|?MetaServerConfiguration?|?+-----+?????+-------------------------------+????????????+--------------------+
?????????????????????????????+-------------------------+???????|?????+----------------------+
???????????????????????????????????????????????????????????????+-->??|ResourceConfiguration?|
???????????????????????????????????????????????????????????????|?????+----------------------+
???????????????????????????????????????????????????????????????|?????+---------------------------+
???????????????????????????????????????????????????????????????+-->??|MetaServerTaskConfiguration|
???????????????????????????????????????????????????????????????|?????+---------------------------+
???????????????????????????????????????????????????????????????|?????+---------------------+
???????????????????????????????????????????????????????????????+-->??|ExecutorConfiguation?|
???????????????????????????????????????????????????????????????|?????+---------------------+
???????????????????????????????????????????????????????????????|?????+--------------------+
???????????????????????????????????????????????????????????????+-->??|MetaDBConfiguration?|
?????????????????????????????????????????????????????????????????????+--------------------+
手機(jī)上閱讀如下:
關(guān)于handler配置,進(jìn)一步細(xì)化如下圖
???????????????????????????????(Init)????????????????????????????????????????????????????????????????????????????????????????????????????????????????+-->??sessionConnectionHandler
????????????????????????????????????????????????????????????????????????????????????????????????????????????????|
????????????????????????????????????????????????????????????????????????????????????????????????????????????????|
????????????????????????????????????????????????????????????????????????????????????????????????????????????????+-->??sessionNodeHandler
?????????????????????????????????????????????????????????????????????????????????????+-----------------------+??|
??????????????????????????????????????????????????????????????????????????????+--->??|?sessionServerHandlers?+--+
????????????????????????????????????????+---------------------+???????????????|??????+-----------------------+??+-->??renewNodesRequestHandler
??????????????????????????????????+-->??|?MetaServerBootstrap?|???????????????|?????????????????????????????????|
??????????????????????????????????|?????+---------------------+???????????????|?????????????????????????????????|
??????????????????????????????????|?????+---------------------------------+???|?????????????????????????????????+-->??getNodesRequestHandler
??????????????????????????????????+-->??|MetaServerConfigBeanConfiguration|???|?????????????????????????????????|
??????????????????????????????????|?????+---------------------------------+???|?????????????????????????????????|
??????????????????????????????????|?????+------------------------------+??????|?????????????????????????????????+-->??fetchProvideDataRequestHandler
??????????????????????????????????+-->??|MetaServerServiceConfiguration|??????|
??????????????????????????????????|?????+------------------------------+??????|
??????????????????????????????????|?????+---------------------------------+???|?????????????????????????????????+-->??dataConnectionHandler
??????????????????????????????????+-->??|MetaServerRepositoryConfiguration+---+?????????????????????????????????|
??????????????????????????????????|?????+---------------------------------+???|?????????????????????????????????|
??????????????????????????????????|?????+-------------------------------+?????|??????+--------------------+?????+-->??getNodesRequestHandler
+-------------------------+???????+-->??|MetaServerRemotingConfiguration|?????+--->??|?dataServerHandlers?+-----+
|?MetaServerConfiguration?|?+-----+?????+-------------------------------+?????|??????+--------------------+?????|
+-------------------------+???????|?????+----------------------+??????????????|?????????????????????????????????+-->??dataNodeHandler
??????????????????????????????????+-->??|ResourceConfiguration?|??????????????|?????????????????????????????????|
??????????????????????????????????|?????+----------------------+??????????????|?????????????????????????????????|
??????????????????????????????????|?????+---------------------------+?????????|?????????????????????????????????+-->??renewNodesRequestHandler
??????????????????????????????????+-->??|MetaServerTaskConfiguration|?????????|?????????????????????????????????|
??????????????????????????????????|?????+---------------------------+?????????|?????????????????????????????????|
??????????????????????????????????|?????+---------------------+???????????????|?????????????????????????????????+-->??fetchProvideDataRequestHandler
??????????????????????????????????+-->??|ExecutorConfiguation?|???????????????|
??????????????????????????????????|?????+---------------------+???????????????|
??????????????????????????????????|?????+--------------------+????????????????|
??????????????????????????????????+-->??|MetaDBConfiguration?|????????????????|?????????????????????????????????+--->?metaConnectionHandler
????????????????????????????????????????+--------------------+????????????????|??????+--------------------+?????|
??????????????????????????????????????????????????????????????????????????????+---->?|?metaServerHandlers?+-----+
?????????????????????????????????????????????????????????????????????????????????????+--------------------+?????+--->?getNodesRequestHandler
手機(jī)上如圖
這個就對應(yīng)了參考中的圖例:
MetaServer 在啟動時,會啟動三個 Bolt Server,并且注冊 Processor Handler,處理對應(yīng)的請求:
meta-server- DataServer:處理 DataNode 相關(guān)的請求;
- SessionServer:處理 SessionNode 相關(guān)的請求;
- MetaServer:處理MetaNode相關(guān)的請求;
0x06 啟動
系統(tǒng)是通過對MetaServerBootstrap的控制來完成了啟動。
MetaServer 模塊的各個 bean 在 JavaConfig 中統(tǒng)一配置,JavaConfig 類為 MetaServerConfiguration。
啟動入口類為 MetaServerInitializerConfiguration,該類不由 JavaConfig 管理配置,而是繼承了 SmartLifecycle 接口,在啟動時由 Spring 框架調(diào)用其 start 方法。
public?class?MetaServerInitializerConfiguration?implements?SmartLifecycle?{????@Autowired
????private?MetaServerBootstrap?metaServerBootstrap;
????@Override
????public?void?start()?{
?????metaServerBootstrap.start();
???MetaServerInitializerConfiguration.this.running.set(true);
????}
????@Override
????public?void?stop()?{
????????this.running.set(false);
????????metaServerBootstrap.destroy();
????}
}
具體見下圖,因為 metaServerBootstrap 是通過配置生成,所以init過程指向配置部分。
???????????????????????????????(Init)????????????????????????+------------------------------------+??start,stop
????????????????????????|?MetaServerInitializerConfiguration?+----------------+
????????????????????????+--------------+---------------------+????????????????|
???????????????????????????????????????^??????????????????????????????????????|
???????????????????????????????????????|??????????????????????????????????????|
???????????????????????????????????????|??????????????????????????????????????|
???????????????????????????????????????|??????????????????????????????????????|
???????????????????????????????????????|??????????????????????????????????????v
???????????????????????????????????????|?????????????????????????????+---------------------+
???????????????????????????????????????|???????????????????????+-->??|?MetaServerBootstrap?|
+-------------------+??????????????????|???????????????????????|?????+---------------------+
|?@EnableMetaServer?|??????????????????|???????????????????????|?????+---------------------------------+
|???????????????????|??????????????????|???????????????????????+-->??|MetaServerConfigBeanConfiguration|
|??MetaApplication??|??????????????????|???????????????????????|?????+---------------------------------+
+--------------+----+??????????????????|???????????????????????|?????+------------------------------+?????????????+-----------------------+
???????????????|???????????????????????|???????????????????????+-->??|MetaServerServiceConfiguration|??????+--->??|?sessionServerHandlers?|
???????????????|???????????????????????|???????????????????????|?????+------------------------------+??????|??????+-----------------------+
???????????????|???????????????????????|???????????????????????|?????+---------------------------------+???|??????+--------------------+
???????????????|???????????????????????|???????????????????????+-->??|MetaServerRepositoryConfiguration+------->??|?dataServerHandlers?|
???????????????|???????????????????????|???????????????????????|?????+---------------------------------+???|??????+--------------------+
???????????????|???????????????????????|?(Configuration)???????|?????+-------------------------------+?????|??????+--------------------+
???????????????|?????????????+---------+---------------+???????+-->??|MetaServerRemotingConfiguration|?????+--->??|?metaServerHandlers?|
???????????????+----------->?|?MetaServerConfiguration?|?+-----+?????+-------------------------------+????????????+--------------------+
?????????????????????????????+-------------------------+???????|?????+----------------------+
???????????????????????????????????????????????????????????????+-->??|ResourceConfiguration?|
???????????????????????????????????????????????????????????????|?????+----------------------+
???????????????????????????????????????????????????????????????|?????+---------------------------+
???????????????????????????????????????????????????????????????+-->??|MetaServerTaskConfiguration|
???????????????????????????????????????????????????????????????|?????+---------------------------+
???????????????????????????????????????????????????????????????|?????+---------------------+
???????????????????????????????????????????????????????????????+-->??|ExecutorConfiguation?|
???????????????????????????????????????????????????????????????|?????+---------------------+
???????????????????????????????????????????????????????????????|?????+--------------------+
???????????????????????????????????????????????????????????????+-->??|MetaDBConfiguration?|
?????????????????????????????????????????????????????????????????????+--------------------+
手機(jī)上如下
6.1 架構(gòu)
MetaServerBootstrap是核心啟動類,該類主要包含了三類組件:外部節(jié)點通信組件、Raft 服務(wù)通信組件、定時器組件。
外部節(jié)點通信組件:在該類中有幾個 Server 通信對象,用于和其它外部節(jié)點進(jìn)行通信。其中 httpServer 主要提供一系列 http 接口,用于 dashboard 管理、數(shù)據(jù)查詢等;sessionServer 主要是處理一些session相關(guān)的服務(wù);dataServer 則負(fù)責(zé)數(shù)據(jù)相關(guān)服務(wù);metaServer 負(fù)責(zé)meta server的注冊;
Raft 服務(wù) :用于集群間的變更和數(shù)據(jù)同步,raftExchanger 就起到這個作用;
定時器組件:例如定時檢測節(jié)點信息、定時檢測數(shù)據(jù)版本信息;具體可見 ExecutorManager,這是一個啟動各種管理線程的地方。他的啟動設(shè)置是在 MetaServerBootstrap.initRaft ?之中 。
6.2 類定義
MetaServerBootstrap的定義如下:
public?class?MetaServerBootstrap?{????@Autowired
????private?MetaServerConfig??????????????????metaServerConfig;
????@Autowired
????private?Exchange??????????????????????????boltExchange;
????@Autowired
????private?Exchange??????????????????????????jerseyExchange;
????@Autowired
????private?ExecutorManager???????????????????executorManager;
????@Resource(name?=?"sessionServerHandlers")
????private?Collection?sessionServerHandlers;@Resource(name?=?"dataServerHandlers")private?Collection?dataServerHandlers;@Resource(name?=?"metaServerHandlers")private?Collection?metaServerHandlers;@Autowiredprivate?ResourceConfig????????????????????jerseyResourceConfig;@Autowiredprivate?ApplicationContext????????????????applicationContext;@Autowiredprivate?RaftExchanger?????????????????????raftExchanger;private?Server????????????????????????????sessionServer;private?Server????????????????????????????dataServer;private?Server????????????????????????????metaServer;private?Server????????????????????????????httpServer;
}
可以參見下圖
?????????????????????????????????????????????????????????????????????????????????????????+-----------------+?????????????????????????????????????????????????????????????????????????????????+---->??|?metaServerConfig|
?????????????????????????????????????????????????????????????????????????????????|???????+-----------------+
?????????????????????????????????????????????????????????????????????????????????|???????+--------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|?boltExchange?|
?????????????????????????????????????????????????????????????????????????????????|???????+--------------+
?????????????????????????????????????????????????????????????????????????????????|???????+--------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|jerseyExchange|
?????????????????????????????????????????????????????????????????????????????????|???????+--------------+
?????????????????????????????????????????????????????????????????????????????????|???????+---------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|executorManager|
?????????????????????????????????????????????????????????????????????????????????|???????+---------------+
?????????????????????????????????????????????????????????????????????????????????|???????+---------------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|sessionServerHandlers|
?????????????????????????????????????????????????????????????????????????????????|???????+---------------------+
?????????????????????????????????????????????????????????????????????????????????|???????+-----------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|dataServerHandler|
???????(Init)????????????????????????????????????????????????????????????????????|???????+-----------------+
+------------------------------------+??start,stop???+---------------------+?????|???????+------------------+
|?MetaServerInitializerConfiguration?+------------->?|?MetaServerBootstrap?|?+-------->??|metaServerHandlers|
+------------------------------------+???????????????+---------------------+?????|???????+------------------+
?????????????????????????????????????????????????????????????????????????????????|???????+-------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|raftExchanger|
?????????????????????????????????????????????????????????????????????????????????|???????+-------------+
?????????????????????????????????????????????????????????????????????????????????|???????+-------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|sessionServer|
?????????????????????????????????????????????????????????????????????????????????|???????+-------------+
?????????????????????????????????????????????????????????????????????????????????|???????+-----------+
?????????????????????????????????????????????????????????????????????????????????+---->??|dataServer?|
?????????????????????????????????????????????????????????????????????????????????|???????+-----------+
?????????????????????????????????????????????????????????????????????????????????|???????+-----------+
?????????????????????????????????????????????????????????????????????????????????+---->??|metaServer?|
?????????????????????????????????????????????????????????????????????????????????|???????+-----------+
?????????????????????????????????????????????????????????????????????????????????|???????+----------+
?????????????????????????????????????????????????????????????????????????????????+---->??|httpServer|
?????????????????????????????????????????????????????????????????????????????????|???????+----------+
?????????????????????????????????????????????????????????????????????????????????|???????+---------------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|jerseyResourceConfig?|
?????????????????????????????????????????????????????????????????????????????????|???????+---------------------+
?????????????????????????????????????????????????????????????????????????????????|???????+-------------------+
?????????????????????????????????????????????????????????????????????????????????+---->??|applicationContext?|
?????????????????????????????????????????????????????????????????????????????????????????+-------------------+
手機(jī)參見下圖
6.3 通信 Exchange
因為前面代碼中有
@Autowiredprivate?Exchange??????????????????????????boltExchange;
@Autowired
private?Exchange??????????????????????????jerseyExchange;
這里要特殊說明下Exchange。
Exchange 作為 Client / Server 連接的抽象,負(fù)責(zé)節(jié)點之間的連接。在建立連接中,可以設(shè)置一系列應(yīng)對不同任務(wù)的 handler (稱之為 ChannelHandler),這些 ChannelHandler 有的作為 Listener 用來處理連接事件,有的作為 Processor 用來處理各種指定的事件,比如服務(wù)信息數(shù)據(jù)變化、Subscriber 注冊等事件。
圖4 - 每一層各司其職,協(xié)同實現(xiàn)節(jié)點通信圖 - 每一層各司其職,協(xié)同實現(xiàn)節(jié)點通信
各種節(jié)點在啟動的時候,利用 Exchange 設(shè)置了一系列 ChannelHandler,比如:
private?void?openDataRegisterServer()?{????try?{
????????if?(dataStart.compareAndSet(false,?true))?{
????????????dataServer?=?boltExchange.open(new?URL(NetUtil.getLocalAddress().getHostAddress(),
????????????????metaServerConfig.getDataServerPort()),?dataServerHandlers
????????????????.toArray(new?ChannelHandler[dataServerHandlers.size()]));
????????}
????}?
}
6.4 啟動入口
前面已經(jīng)提到,啟動入口類為 MetaServerInitializerConfiguration,該類不由 JavaConfig 管理配置,而是繼承了 SmartLifecycle 接口,在啟動時由 Spring 框架調(diào)用其 start 方法。
該方法中調(diào)用了 MetaServerBootstrap # start 方法,用于啟動一系列的初始化服務(wù)。
import?org.springframework.beans.factory.annotation.Autowired;import?org.springframework.context.SmartLifecycle;
public?class?MetaServerInitializerConfiguration?implements?SmartLifecycle?{
????@Autowired
????private?MetaServerBootstrap?metaServerBootstrap;‘
??????
????@Override
????public?void?start()?{
????????????metaServerBootstrap.start();
????????????MetaServerInitializerConfiguration.this.running.set(true);
????}
}??
6.4.1 啟動服務(wù)Server
前面提到,MetaServerBootstrap 在啟動時,會啟動三個 Bolt Server,并且注冊 Processor Handler,處理對應(yīng)的請求:
- DataServer:處理 DataNode 相關(guān)的請求;
- SessionServer:處理 SessionNode 相關(guān)的請求;
- MetaServer:處理MetaNode相關(guān)的請求;
然后啟動 HttpServer, 用于處理 Admin 請求,提供推送開關(guān),集群數(shù)據(jù)查詢等 Http 接口。
最后啟動 Raft 服務(wù), 每個節(jié)點同時作為 RaftClient 和 RaftServer, 用于集群間的變更和數(shù)據(jù)同步。為支持高可用特性,對于 MetaServer 來說,存儲了 SOFARegistry 的元數(shù)據(jù),為了保障 MetaServer 集群的一致性,其采用了 Raft 協(xié)議來進(jìn)行選舉和復(fù)制。
具體代碼參見:
public?void?start()?{????????openSessionRegisterServer();
????????openDataRegisterServer();
????????openMetaRegisterServer();
????????openHttpServer();
????????initRaft();
}
private?void?openHttpServer()?{
????????if?(httpStart.compareAndSet(false,?true))?{
????????????bindResourceConfig();
????????????httpServer?=?jerseyExchange.open(
????????????????new?URL(NetUtil.getLocalAddress().getHostAddress(),?metaServerConfig
????????????????????.getHttpServerPort()),?new?ResourceConfig[]?{?jerseyResourceConfig?});
????????}
}
private?void?initRaft()?{
????raftExchanger.startRaftServer(executorManager);
????raftExchanger.startRaftClient();
????raftExchanger.startCliService();
}
6.4.1.1 BoltServer
Raft 和 Bolt 是SOFA所特殊實現(xiàn),所以我們暫不介紹其底層機(jī)制,以后有機(jī)會單獨開篇,下面提一下三個BoltServer。
private?void?openSessionRegisterServer()?{????????if?(sessionStart.compareAndSet(false,?true))?{
????????????sessionServer?=?boltExchange
????????????????.open(
????????????????????new?URL(NetUtil.getLocalAddress().getHostAddress(),?metaServerConfig
????????????????????????.getSessionServerPort()),?sessionServerHandlers
????????????????????????.toArray(new?ChannelHandler[sessionServerHandlers.size()]));
????????}
}
private?void?openDataRegisterServer()?{
????????if?(dataStart.compareAndSet(false,?true))?{
????????????dataServer?=?boltExchange.open(new?URL(NetUtil.getLocalAddress().getHostAddress(),
????????????????metaServerConfig.getDataServerPort()),?dataServerHandlers
????????????????.toArray(new?ChannelHandler[dataServerHandlers.size()]));
????????}
}
private?void?openMetaRegisterServer()?{
????????if?(metaStart.compareAndSet(false,?true))?{
????????????metaServer?=?boltExchange.open(new?URL(NetUtil.getLocalAddress().getHostAddress(),
????????????????metaServerConfig.getMetaServerPort()),?metaServerHandlers
????????????????.toArray(new?ChannelHandler[metaServerHandlers.size()]));
????????}
}
這幾個Server的handler就是我們前面配置的
@Resource(name?=?"sessionServerHandlers")private?Collection?sessionServerHandlers;@Resource(name?=?"dataServerHandlers")private?Collection?dataServerHandlers;@Resource(name?=?"metaServerHandlers")private?Collection?metaServerHandlers;
具體參見下圖:
????????????????????????????????????????????????????????????????????????????????????????????????????????+------------------------+????????????????????????????????????+-----------------+???????????????????????????????????????????+--->?|sessionConnectionHandler|
????????????????????????????+---->??|?metaServerConfig|???????????????????????????????????????????|?????+------------------------+
????????????????????????????|???????+-----------------+???????????????????????????????????????????|?????+-------------------+
????????????????????????????|???????+--------------+??????????????????????????????????????????????+--->?|sessionNodeHandler?|
????????????????????????????+---->??|?boltExchange?|??????????????????????????????????????????+-->+?????+-------------------+
????????????????????????????|???????+--------------+??????????????????????????????????????????|???|?????+------------------------+
????????????????????????????|???????+--------------+??????????????????????????????????????????|???+--->?|renewNodesRequestHandler|
????????????????????????????+---->??|jerseyExchange|??????????????????????????????????????????|???|?????+------------------------+
????????????????????????????|???????+--------------+??????????????????????????????????????????|???|?????+----------------------+
????????????????????????????|???????+---------------+?????????????????????????????????????????|???+--->?|getNodesRequestHandler|
????????????????????????????+---->??|executorManager|?????????????????????????????????????????|???|?????+----------------------+
????????????????????????????|???????+---------------+???????????????+---------------------+???|???|?????+------------------------------+
????????????????????????????+------------------------------------->?|sessionServerHandlers+---+???+--->?|fetchProvideDataRequestHandler|
????????????????????????????|???????+-------------+?????????????????+---------------------+?????????????+------------------------------+
????????????????????????????+---->??|sessionServer|?+------------------^
????????????????????????????|???????+-------------+?????????????????????????????????????????????????????+---------------------+
????????????????????????????|?????????????????????????????????????????????????????????????????????---->?|dataConnectionHandler|
????????????????????????????|???????????????????????????????????????+------------------+??????????|?????+---------------------+
+---------------------+?????+------------------------------------->?|dataServerHandlers+----------+?????+----------------------+
|?MetaServerBootstrap?|?+---+???????+-----------+???????????????????+------------------+??????????+--->?|getNodesRequestHandler|
+---------------------+?????+---->??|dataServer?+----------------------^??????????????????????????|?????+----------------------+
????????????????????????????|???????+-----------+?????????????????????????????????????????????????|?????+---------------+
????????????????????????????|?????????????????????????????????????????????????????????????????????+--->?|dataNodeHandler|
????????????????????????????|???????????????????????????????????????+------------------+??????????|?????+---------------+
????????????????????????????+------------------------------------>??|metaServerHandlers+------+???|?????+------------------------+
????????????????????????????|???????+-----------+???????????????????+------------------+??????|???+--->?|renewNodesRequestHandler|
????????????????????????????+---->??|metaServer?+----------------------^??????????????????????|???|?????+------------------------+
????????????????????????????|???????+-----------+?????????????????????????????????????????????|???|?????+------------------------------+
????????????????????????????|?????????????????????????????????????????????????????????????????|???+--->?|fetchProvideDataRequestHandler|
????????????????????????????|???????+-------------+???????????????????????????????????????????|?????????+------------------------------+
????????????????????????????+---->??|raftExchanger|???????????????????????????????????????????|
????????????????????????????|???????+-------------+???????????????????????????????????????????|
????????????????????????????|?????????????????????????????????????????????????????????????????|
????????????????????????????|???????+----------+??????????????????????????????????????????????|
????????????????????????????+---->??|httpServer|??????????????????????????????????????????????|??????????+---------------------+
????????????????????????????|???????+----------+??????????????????????????????????????????????|????+-->??|metaConnectionHandler|
????????????????????????????|???????+---------------------+???????????????????????????????????+---->?????+---------------------+
????????????????????????????+---->??|jerseyResourceConfig?|????????????????????????????????????????|?????+---------------------+
????????????????????????????|???????+---------------------+????????????????????????????????????????+-->??|getNodesRequestHandle|
????????????????????????????|???????+-------------------+????????????????????????????????????????????????+---------------------+
????????????????????????????+---->??|applicationContext?|
????????????????????????????????????+-------------------+
手機(jī)上
在初始化時候,大致堆棧如下 ?:
interest:55,?RenewNodesRequestHandler?(com.alipay.sofa.registry.server.meta.remoting.handler)interest:61,?SyncUserProcessorAdapter?(com.alipay.sofa.registry.remoting.bolt)
registerUserProcessor:42,?UserProcessorRegisterHelper?(com.alipay.remoting.rpc.protocol)
registerUserProcessor:376,?RpcServer?(com.alipay.remoting.rpc)
registerUserProcessorHandler:159,?BoltServer?(com.alipay.sofa.registry.remoting.bolt)
initHandler:139,?BoltServer?(com.alipay.sofa.registry.remoting.bolt)
startServer:92,?BoltServer?(com.alipay.sofa.registry.remoting.bolt)
open:65,?BoltExchange?(com.alipay.sofa.registry.remoting.bolt.exchange)
open:36,?BoltExchange?(com.alipay.sofa.registry.remoting.bolt.exchange)
openSessionRegisterServer:149,?MetaServerBootstrap?(com.alipay.sofa.registry.server.meta.bootstrap)
start:108,?MetaServerBootstrap?(com.alipay.sofa.registry.server.meta.bootstrap)
start:51,?MetaServerInitializerConfiguration?(com.alipay.sofa.registry.server.meta.bootstrap)
以SessionServer為例,在構(gòu)建過程中,調(diào)用到 ?BoltExchange . open。
private?void?openSessionRegisterServer()?{????????if?(sessionStart.compareAndSet(false,?true))?{
????????????sessionServer?=?boltExchange
????????????????.open(
????????????????????new?URL(NetUtil.getLocalAddress().getHostAddress(),?metaServerConfig
????????????????????????.getSessionServerPort()),?sessionServerHandlers
????????????????????????.toArray(new?ChannelHandler[sessionServerHandlers.size()]));
????????}???
}
BoltExchange中有
@Overridepublic?Server?open(URL?url,?ChannelHandler...?channelHandlers)?{
????BoltServer?server?=?createBoltServer(url,?channelHandlers);
????setServer(server,?url);
????server.startServer();
????return?server;
}
BoltServer中有
public?void?startServer()?{????if?(isStarted.compareAndSet(false,?true))?{
????????????boltServer?=?new?RpcServer(url.getPort(),?true);
????????????initHandler();
????????????boltServer.start();
????}?
}
private?void?initHandler()?{
????????if?(initHandler.compareAndSet(false,?true))?{
????????????boltServer.addConnectionEventProcessor(ConnectionEventType.CONNECT,
????????????????new?ConnectionEventAdapter(ConnectionEventType.CONNECT,
????????????????????getConnectionEventHandler(),?this));
????????????boltServer.addConnectionEventProcessor(ConnectionEventType.CLOSE,
????????????????new?ConnectionEventAdapter(ConnectionEventType.CLOSE,?getConnectionEventHandler(),
????????????????????this));
????????????boltServer.addConnectionEventProcessor(ConnectionEventType.EXCEPTION,
????????????????new?ConnectionEventAdapter(ConnectionEventType.EXCEPTION,
????????????????????getConnectionEventHandler(),?this));
????????????registerUserProcessorHandler();
????????}
}
最后調(diào)用,會設(shè)定同步和異步的handler。
private?void?registerUserProcessorHandler()?{????if?(channelHandlers?!=?null)?{
????????for?(ChannelHandler?channelHandler?:?channelHandlers)?{
????????????if?(HandlerType.PROCESSER.equals(channelHandler.getType()))?{
????????????????if?(InvokeType.SYNC.equals(channelHandler.getInvokeType()))?{
????????????????????boltServer.registerUserProcessor(new?SyncUserProcessorAdapter(
????????????????????????channelHandler));
????????????????}?else?{
????????????????????boltServer.registerUserProcessor(new?AsyncUserProcessorAdapter(
????????????????????????channelHandler));
????????????????}
????????????}
????????}
????}
}
6.4.1.2 HttpServer
以使用 Jetty 的 openHttpServer 為例
啟動 HttpServer, 用于處理 Admin 請求,提供推送開關(guān),集群數(shù)據(jù)查詢等 Http 接口。
public?class?JerseyJettyServer?implements?Server?{????public?static?org.eclipse.jetty.server.Server?createServer(final?URI?uri,final?ResourceConfig?resourceConfig,final?boolean?start)?{
????????JettyHttpContainer?handler?=?ContainerFactory.createContainer(JettyHttpContainer.class,
????????????resourceConfig);
????????int?defaultPort?=?Container.DEFAULT_HTTP_PORT;
????????final?int?port?=?(uri.getPort()?==?-1)???defaultPort?:?uri.getPort();
????????final?org.eclipse.jetty.server.Server?server?=?new?org.eclipse.jetty.server.Server(
????????????new?JettyConnectorThreadPool());
????????final?ServerConnector?http?=?new?ServerConnector(server,?new?HttpConnectionCustomFactory());
????????http.setPort(port);
????????server.setConnectors(new?Connector[]?{?http?});
????????if?(handler?!=?null)?{
????????????server.setHandler(handler);
????????}
????????if?(start)?{
????????????try?{
????????????????//?Start?the?server.
????????????????server.start();
????????????}?
????????}
????????return?server;
????}??
}
其堆棧如下:
:72,?JerseyJettyServer?(com.alipay.sofa.registry.remoting.jersey)open:73,?JerseyExchange?(com.alipay.sofa.registry.remoting.jersey.exchange)
open:40,?JerseyExchange?(com.alipay.sofa.registry.remoting.jersey.exchange)
openHttpServer:205,?MetaServerBootstrap?(com.alipay.sofa.registry.server.meta.bootstrap)
start:114,?MetaServerBootstrap?(com.alipay.sofa.registry.server.meta.bootstrap)
start:51,?MetaServerInitializerConfiguration?(com.alipay.sofa.registry.server.meta.bootstrap)
doStart:173,?DefaultLifecycleProcessor?(org.springframework.context.support)
access$200:50,?DefaultLifecycleProcessor?(org.springframework.context.support)
start:350,?DefaultLifecycleProcessor$LifecycleGroup?(org.springframework.context.support)
startBeans:149,?DefaultLifecycleProcessor?(org.springframework.context.support)
onRefresh:112,?DefaultLifecycleProcessor?(org.springframework.context.support)
finishRefresh:880,?AbstractApplicationContext?(org.springframework.context.support)
refresh:546,?AbstractApplicationContext?(org.springframework.context.support)
refresh:693,?SpringApplication?(org.springframework.boot)
refreshContext:360,?SpringApplication?(org.springframework.boot)
run:303,?SpringApplication?(org.springframework.boot)
run:1118,?SpringApplication?(org.springframework.boot)
run:1107,?SpringApplication?(org.springframework.boot)
main:42,?MetaApplication?(com.alipay.sofa.registry.server.meta)
6.4.1.3 @RaftService
如下存儲由Raft來保證數(shù)據(jù)一致性,后文針對此有詳細(xì)講解。
@RaftService(uniqueId?=?"sessionServer")public?class?SessionVersionRepositoryService?
@RaftService(uniqueId?=?"metaServer")
public?class?MetaRepositoryService??
@RaftService(uniqueId?=?"dataServer")
public?class?DataRepositoryService??
@RaftService(uniqueId?=?"sessionServer")
public?class?SessionRepositoryService???
@RaftService(uniqueId?=?"dataServer")
public?class?DataConfirmStatusService???
@RaftService(uniqueId?=?"sessionServer")
public?class?SessionConfirmStatusService??
6.4.2 ExecutorManager
是一個啟動各種管理線程的地方,都是定期常規(guī)管理任務(wù)。
public?class?ExecutorManager?{????private?ScheduledExecutorService?scheduler;
????private?ThreadPoolExecutor???????heartbeatCheckExecutor;
????private?ThreadPoolExecutor???????checkDataChangeExecutor;
????private?ThreadPoolExecutor???????getOtherDataCenterChangeExecutor;
????private?ThreadPoolExecutor???????connectMetaServerExecutor;
????private?ThreadPoolExecutor???????checkNodeListChangePushExecutor;
????private?ThreadPoolExecutor???????raftClientRefreshExecutor;
????private?MetaServerConfig?????????metaServerConfig;
????@Autowired
????private?Registry?????????????????metaServerRegistry;
????@Autowired
????private?MetaClientExchanger??????metaClientExchanger;
????@Autowired
????private?RaftExchanger????????????raftExchanger;
??
???public?void?startScheduler()?{
????????init();
????????scheduler.schedule(new?TimedSupervisorTask("HeartbeatCheck",?scheduler,?heartbeatCheckExecutor,
????????????????????????metaServerConfig.getSchedulerHeartbeatTimeout(),?TimeUnit.SECONDS,
????????????????????????metaServerConfig.getSchedulerHeartbeatExpBackOffBound(),?()?->?metaServerRegistry.evict()),
????????????????metaServerConfig.getSchedulerHeartbeatFirstDelay(),?TimeUnit.SECONDS);
????????scheduler.schedule(
????????????????new?TimedSupervisorTask("GetOtherDataCenterChange",?scheduler,?getOtherDataCenterChangeExecutor,
????????????????????????metaServerConfig.getSchedulerGetDataChangeTimeout(),?TimeUnit.SECONDS,
????????????????????????metaServerConfig.getSchedulerGetDataChangeExpBackOffBound(),?()?->?{
????????????????????metaServerRegistry.getOtherDataCenterNodeAndUpdate(NodeType.DATA);
????????????????????metaServerRegistry.getOtherDataCenterNodeAndUpdate(NodeType.META);
????????????????}),?metaServerConfig.getSchedulerGetDataChangeFirstDelay(),?TimeUnit.SECONDS);
????????scheduler.schedule(new?TimedSupervisorTask("ConnectMetaServer",?scheduler,?connectMetaServerExecutor,
????????????????????????metaServerConfig.getSchedulerConnectMetaServerTimeout(),?TimeUnit.SECONDS,
????????????????????????metaServerConfig.getSchedulerConnectMetaServerExpBackOffBound(),
????????????????????????()?->?metaClientExchanger.connectServer()),?metaServerConfig.getSchedulerConnectMetaServerFirstDelay(),
????????????????TimeUnit.SECONDS);
????????scheduler.schedule(
????????????????new?TimedSupervisorTask("CheckSessionNodeListChangePush",?scheduler,?checkNodeListChangePushExecutor,
????????????????????????metaServerConfig.getSchedulerCheckNodeListChangePushTimeout(),?TimeUnit.SECONDS,
????????????????????????metaServerConfig.getSchedulerCheckNodeListChangePushExpBackOffBound(),
????????????????????????()?->?metaServerRegistry.pushNodeListChange(NodeType.SESSION)),
????????????????metaServerConfig.getSchedulerCheckNodeListChangePushFirstDelay(),?TimeUnit.SECONDS);
????????scheduler.schedule(
????????????????new?TimedSupervisorTask("CheckDataNodeListChangePush",?scheduler,?checkNodeListChangePushExecutor,
????????????????????????metaServerConfig.getSchedulerCheckNodeListChangePushTimeout(),?TimeUnit.SECONDS,
????????????????????????metaServerConfig.getSchedulerCheckNodeListChangePushExpBackOffBound(),
????????????????????????()?->?metaServerRegistry.pushNodeListChange(NodeType.DATA)),
????????????????metaServerConfig.getSchedulerCheckNodeListChangePushFirstDelay(),?TimeUnit.SECONDS);
????????scheduler.schedule(new?TimedSupervisorTask("RaftClientRefresh",?scheduler,?raftClientRefreshExecutor,
????????????????????????metaServerConfig.getSchedulerCheckNodeListChangePushTimeout(),?TimeUnit.SECONDS,
????????????????????????metaServerConfig.getSchedulerCheckNodeListChangePushExpBackOffBound(),
????????????????????????()?->?raftExchanger.refreshRaftClient()),
????????????????metaServerConfig.getSchedulerCheckNodeListChangePushFirstDelay(),?TimeUnit.SECONDS);
????}??
}
6.4.2.1 啟動
ExecutorManager 的啟動設(shè)置是在 MetaServerBootstrap.initRaft 之中,分別啟動RaftServer,RaftClient,CliService。
private?void?initRaft()?{????raftExchanger.startRaftServer(executorManager);
????raftExchanger.startRaftClient();
????raftExchanger.startCliService();
}
當(dāng) ?Raft 選出 ?Leader 之后,會調(diào)用到 ? ExecutorManager # startScheduler。
- 首先生成各個ThreadPoolExecutor;
- 然后運(yùn)行本身的 各個TimedSupervisorTask,其會調(diào)用不同的handler,比如 ?connectServer,getSchedulerHeartbeatFirstDelay ?等等;
6.4.2.2 TimedSupervisorTask
TimedSupervisorTask 實現(xiàn)了 TimerTask。
public?class?TimedSupervisorTask?extends?TimerTask?{????private?final?ScheduledExecutorService?scheduler;
????private?final?ThreadPoolExecutor???????executor;
????private?final?long?????????????????????timeoutMillis;
????private?final?Runnable?????????????????task;
????private?String?????????????????????????name;
????private?final?AtomicLong???????????????delay;
????private?final?long?????????????????????maxDelay;
????@Override
????public?void?run()?{
????????Future?future?=?null;
????????try?{
????????????future?=?executor.submit(task);
????????????//?block?until?done?or?timeout
????????????future.get(timeoutMillis,?TimeUnit.MILLISECONDS);
????????????delay.set(timeoutMillis);
????????}?catch?{
??????.....
????????}?finally?{
????????????if?(future?!=?null)?{
????????????????future.cancel(true);
????????????}
????????????scheduler.schedule(this,?delay.get(),?TimeUnit.MILLISECONDS);
????????}
????}
}
6.4.2.3 管理任務(wù)
可以看到管理任務(wù)大致有:
- HeartbeatCheck :心跳檢測;
- GetOtherDataCenterChange :查看其他數(shù)據(jù)中心的變化;
- ConnectMetaServer :與其他的MetaServer交互;
- CheckSessionNodeListChangePush :看看Session節(jié)點的變化;
- CheckDataNodeListChangePush :查看數(shù)據(jù)節(jié)點變化;
- RaftClientRefresh :看看Raft 服務(wù)消息;
TimedSupervisorTask 會定期執(zhí)行,比如 ?CheckDataNodeListChangePush ?這個線程會定期執(zhí)行 ?metaServerRegistry.pushNodeListChange(NodeType.DATA)) ?來看看是否有變化。這里就會用到DataNode注冊時候,Confirm的消息。
@Overridepublic?void?pushNodeListChange()?{
????NodeOperator?fireNode;if?((fireNode?=?dataConfirmStatusService.peekConfirmNode())?!=?null)?{
????????NodeChangeResult?nodeChangeResult?=?getNodeChangeResult();
????????Map>?map?=?nodeChangeResult.getNodes();
????????Map?addNodes?=?map.get(nodeConfig.getLocalDataCenter());if?(addNodes?!=?null)?{
????????????Map?previousNodes?=?dataConfirmStatusService.putExpectNodes(
????????????????fireNode.getNode(),?addNodes);if?(!previousNodes.isEmpty())?{
????????????????firePushDataListTask(fireNode,?nodeChangeResult,?previousNodes,?true);
????????????}
????????}
????????firePushSessionListTask(nodeChangeResult,?fireNode.getNodeOperate().toString());
????}
}
再比如定期去除過期的Node:
public?class?MetaServerRegistry?implements?Registry<Node>?{????@Override
????public?void?evict()?{
????????for?(NodeType?nodeType?:?NodeType.values())?{
????????????StoreService?storeService?=?ServiceFactory.getStoreService(nodeType);
????????????if?(storeService?!=?null)?{
????????????????Collection?expiredNodes?=?storeService.getExpired();if?(expiredNodes?!=?null?&&?!expiredNodes.isEmpty())?{
????????????????????storeService.removeNodes(expiredNodes);
????????????????}
????????????}
????????}
????}??
}
6.4.3 ServiceFactory
ServiceFactory 需要特殊說明,它提供了系統(tǒng)所需要的一系列服務(wù)。特殊之處在于,ServiceFactory 不是由 MetaServerBootstrap 負(fù)責(zé)啟動,而是由 Spring 負(fù)責(zé)啟動。因為 ServiceFactory 繼承了ApplicationContextAware,所以啟動時候生成。
在Web應(yīng)用中,Spring容器通常采用聲明式方式配置產(chǎn)生:開發(fā)者只要在web.xml中配置一個Listener,該Listener將會負(fù)責(zé)初始化Spring容器,MVC框架可以直接調(diào)用Spring容器中的Bean,無需訪問Spring容器本身。在這種情況下,容器中的Bean處于容器管理下,無需主動訪問容器,只需接受容器的依賴注入即可。
但在某些特殊的情況下,Bean需要實現(xiàn)某個功能,但該功能必須借助于Spring容器才能實現(xiàn),此時就必須讓該Bean先獲取Spring容器,然后借助于Spring容器實現(xiàn)該功能。為了讓Bean獲取它所在的Spring容器,可以讓該Bean實現(xiàn)ApplicationContextAware接口。
下面代碼可以看出來,啟動了一系列服務(wù)。
public?class?ServiceFactory?implements?ApplicationContextAware?{????private?static?Map???????storeServiceMap???=?new?HashMap<>();private?static?Map?connectManagerMap?=?new?HashMap<>();private?static?Map????????nodeServiceMap????=?new?HashMap<>();??
}
storeServiceMap?=?{HashMap@5107}??size?=?3
?{Node$NodeType@5525}?"SESSION"?->?{SessionStoreService@5526}?
??key?=?{Node$NodeType@5525}?"SESSION"
??value?=?{SessionStoreService@5526}?
?{Node$NodeType@4815}?"DATA"?->?{DataStoreService@5527}?
??key?=?{Node$NodeType@4815}?"DATA"
??value?=?{DataStoreService@5527}?
?{Node$NodeType@5528}?"META"?->?{MetaStoreService@5529}?
??key?=?{Node$NodeType@5528}?"META"
??value?=?{MetaStoreService@5529}?
connectManagerMap?=?{HashMap@5532}??size?=?3
?{Node$NodeType@5525}?"SESSION"?->?{SessionConnectionHandler@5548}?
??key?=?{Node$NodeType@5525}?"SESSION"
??value?=?{SessionConnectionHandler@5548}?
?{Node$NodeType@4815}?"DATA"?->?{DataConnectionHandler@5549}?
??key?=?{Node$NodeType@4815}?"DATA"
??value?=?{DataConnectionHandler@5549}?
?{Node$NodeType@5528}?"META"?->?{MetaConnectionHandler@5550}?
??key?=?{Node$NodeType@5528}?"META"
??value?=?{MetaConnectionHandler@5550}?
nodeServiceMap?=?{HashMap@5533}??size?=?3
?{Node$NodeType@5525}?"SESSION"?->?{SessionNodeServiceImpl@5540}?
??key?=?{Node$NodeType@5525}?"SESSION"
??value?=?{SessionNodeServiceImpl@5540}?
?{Node$NodeType@4815}?"DATA"?->?{DataNodeServiceImpl@5541}?
??key?=?{Node$NodeType@4815}?"DATA"
??value?=?{DataNodeServiceImpl@5541}?
?{Node$NodeType@5528}?"META"?->?{MetaNodeServiceImpl@5542}?
??key?=?{Node$NodeType@5528}?"META"
??value?=?{MetaNodeServiceImpl@5542}?
至此,MetaServer的架構(gòu)和啟動介紹完成,我們下文將會介紹基本功能,比如注冊,存儲,續(xù)約等。
0xFF 參考
服務(wù)注冊中心 MetaServer 功能介紹和實現(xiàn)剖析 | SOFARegistry 解析
服務(wù)注冊中心如何實現(xiàn) DataServer 平滑擴(kuò)縮容 | SOFARegistry 解析
服務(wù)注冊中心數(shù)據(jù)一致性方案分析 | SOFARegistry 解析
服務(wù)注冊中心如何實現(xiàn)秒級服務(wù)上下線通知 | SOFARegistry 解析
服務(wù)注冊中心 Session 存儲策略 | SOFARegistry 解析
服務(wù)注冊中心數(shù)據(jù)分片和同步方案詳解 | SOFARegistry 解析
服務(wù)注冊中心 SOFARegistry 解析 | 服務(wù)發(fā)現(xiàn)優(yōu)化之路
海量數(shù)據(jù)下的注冊中心 - SOFARegistry 架構(gòu)介紹
服務(wù)端部署
客戶端使用
全面理解Raft協(xié)議
詳解螞蟻金服 SOFAJRaft | 生產(chǎn)級高性能 Java 實現(xiàn)
從JRaft來看Raft協(xié)議實現(xiàn)細(xì)節(jié)
SOFAJRaft—初次使用
JRaft 用戶指南 & API 詳解
怎樣打造一個分布式數(shù)據(jù)庫——rocksDB, raft, mvcc,本質(zhì)上是為了解決跨數(shù)據(jù)中心的復(fù)制
sofa-bolt源碼閱讀(5)-日志
Raft 為什么是更易理解的分布式一致性算法
SOFAJRaft 源碼分析一(啟動流程和節(jié)點變化)
SOFAJRaft 實現(xiàn)原理 - 生產(chǎn)級 Raft 算法庫存儲模塊剖析
客戶端使用
總結(jié)
以上是生活随笔為你收集整理的源码 状态机_[源码阅读] 阿里SOFA服务注册中心MetaServer(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开封看精子不液化最好的医院推荐
- 下一篇: android 代码设置 键盘适应_硬核