服務注冊中心簡介
在分布式系統中,服務注冊中心的作用是將部署服務實例的機器地址以及其它元數據記錄到注冊中心,服務消費者在有需求的時候,通過查詢注冊中心,輸入提供的服務名,獲取到地址,從而發起調用。
在微服務架構下,主要有三種角色:服務提供者(RPC Server)、服務消費者(RPC Client) 和 服務注冊中心(Registry),三者的交互關系請看下面這張圖:
RPC Server 提供服務,在啟動時,根據配置文件指定的服務注冊中心配置信息,向 Registry 注冊自身的服務路由,並向Registry定期發送心跳匯報存活狀態。
RPC Client 調用服務,在啟動時,根據配置文件指定的服務注冊中心配置信息,向 Registry 訂閱服務,把Registry返回的服務節點列表緩存在本地內存中,並與 RPC Sever 建立連接。
當 RPC Server 節點發生變更時,Registry會同步變更,RPC Client 感知后會刷新本地內存中緩存的服務節點列表。
RPC Client 從本地緩存的服務節點列表中,基於負載均衡算法選擇一台 RPC Sever 發起調用。
::: tip 提示
- 對於一個微服務應用來說,在集群中,它既可以作為RPC Sever,也可能作為RPC Client,主要是看在rpc通信過程中,是提供服務的一方,還是調用服務的一方。
:::
當前, silky微服務框架支持使用 Zookeeper 、 Nacos 、 Consul 作為服務注冊中心,開發者可以選擇熟悉的服務中間件作為服務注冊中心。
服務元數據
在silky框架中,服務提供者向服務注冊中心注冊的數據被稱為: 服務元數據 。服務元數據主要四部分組成:
- hostName : 用於描述服務提供者的名稱,為構建主機的包名稱
- services : 該服務提供者所提供的應用服務信息,是一個數組,包括:服務Id,服務名稱,服務協議,服務條目,元數據等信息
- timeStamp : 更新服務元數據的時間戳
- endpoints : 該服務實例的終結點,是一個數組。不同服務注冊中心注冊服務實例的終結點不同
如果使用 Zookeeper 作為服務注冊中心, 所有的服務元數據將會被維護到該主機所在節點下, 注冊到 Zookeeper 服務注冊中心的服務元數據如下:
{
"hostName":"DemoHost",
"services":[
{
"id":"Demo.Application.Contracts.System.ISystemAppService",
"serviceName":"SystemAppService",
"serviceProtocol":0,
"serviceEntries":[
{
"id":"Demo.Application.Contracts.System.ISystemAppService.GetInfo_Get",
"serviceId":"Demo.Application.Contracts.System.ISystemAppService",
"serviceName":"SystemAppService",
"method":"GetInfo",
"webApi":"api/system/demo/info",
"httpMethod":0,
"serviceProtocol":0,
"metadatas":{
},
"prohibitExtranet":false,
"isAllowAnonymous":true,
"isDistributeTransaction":false
}
],
"metadatas":{
}
}
],
"endpoints":[
{
"host":"172.26.144.1",
"port":2200,
"processorTime":2578.125,
"timeStamp":1636464575,
"serviceProtocol":0
}
],
"timeStamp":1636464576
}
如果服務注冊中心是 Consul 或是 Nacos, 服務實例的終結點則會單獨注冊和維護, 服務元數據格式如下:
{
"hostName":"DemoHost",
"services":[
{
"id":"Demo.Application.Contracts.System.ISystemAppService",
"serviceName":"SystemAppService",
"serviceProtocol":0,
"serviceEntries":[
{
"id":"Demo.Application.Contracts.System.ISystemAppService.GetInfo_Get",
"serviceId":"Demo.Application.Contracts.System.ISystemAppService",
"serviceName":"SystemAppService",
"method":"GetInfo",
"webApi":"api/system/demo/info",
"httpMethod":0,
"serviceProtocol":0,
"metadatas":{
},
"prohibitExtranet":false,
"isAllowAnonymous":true,
"isDistributeTransaction":false
}
],
"metadatas":{
}
}
],
"timeStamp":1636464576
}
主機名稱(hostName)
hostName 用於描述服務提供者的名稱,在向服務注冊中心注冊服務的過程中,應用會判斷服務注冊中心是否存在該應用的服務元數據,如果不存在,則創建相應的節點,並添加相應的服務元數據;如果已經存在相應的服務節點,則會更新服務元數據,其他服務提供者的實例從服務注冊中心獲取到服務元數據,並更新本地內存的服務元數據。
服務列表(services)
該屬性包含該應用所支持的服務列表,如果服務注冊中心的服務列表被更新,其他服務實例也會從服務注冊中心獲取,並更新到本地內存。
服務列表包括:服務Id,服務名稱,服務協議,服務條目,元數據等信息
字段 | 說明 | 備注 |
---|---|---|
id | 服務Id | 具有唯一性;服務接口定義的完全限定名 |
serviceName | 服務名稱 | |
serviceProtocol | 服務通信協議 | rpc通信框架中,采用的通信協議 |
serviceEntries | 該服務支持的服務條目(即:應用服務定義的方法) | 數據類型為數組 |
serviceEntries.id | 服務條目Id | 方法的完全限定名 + 參數名 + Http方法名 |
serviceEntries.serviceId | 服務Id | |
serviceEntries.serviceName | 服務名稱 | |
serviceEntries.method | 服務條目對應的方法名稱 | |
serviceEntries.webApi | 生成的webapi 地址 | 如果被禁止訪問外網則為空 |
serviceEntries.httpMethod | 生成的webapi的請求地址 | 如果被禁止訪問外網則為空 |
serviceEntries.serviceProtocol | rpc通信框架中,采用的通信協議 | |
serviceEntries.metadatas | 服務條目的元數據 | 可以為服務條目寫入(k,v)格式的元數據 |
metadatas | 服務的其他元數據 | 可以為服務寫入(k,v)格式的元數據 |
::: warning 注意
- 在一個微服務集群中,服務條目具有唯一性。也就是說,不允許在同一個微服務集群中, 不同微服務應用中不允許出現兩個一模一樣的方法(應用服務接口的完全限定名和方法名、參數名一致);
- 只有被實現的應用服務才會被注冊到服務注冊中心。
:::
終結點
endpoints 是用來描述該微服務的服務實例的地址信息。
一個服務實例可能存在多個終結點,如:使用webhost構建的微服務應用(存在web地址終結點和rpc終結點地址);構建支持websocket服務的微服務應用(存在websocket服務地址終結點和rpc終結點地址)。
使用不同的服務注冊中心,注冊終結點可能會做不同的處理。
- 如果使用 Zookeeper 作為服務注冊中心, 服務實例的終結點將被更新到該服務提供者對應節點數據的
endpoints
屬性,也就是說,endpoints
將作為服務元數據的一個屬性。
{
"hostName": "DemoHost",
"services": ["..."],
"timeStamp": 1636464576,
"endpoints":[
{
"host":"localhost",
"port":5000,
"processorTime":2984.375,
"timeStamp":1636464576,
"serviceProtocol":4
},
{
"host":"172.26.144.1",
"port":2200,
"processorTime":2578.125,
"timeStamp":1636464575,
"serviceProtocol":0
}
]
}
- 如果使用 Consul 作為服務注冊中心, 服務實例將會被注冊到 Services 節點,並且只會注冊協議為
TCP
的終結點,服務實例的其他協議的將會以元數據的方式添加到元數據
- 如果使用 Nacos 作為服務注冊中心, 服務將會被注冊到服務列表節點,與使用 Consul 作為服務注冊中心相同,只會注冊協議為
TCP
的終結點,服務實例的其他協議的將會以元數據的方式添加到元數據
終結點的屬性如下所述:
字段 | 說明 | 備注 |
---|---|---|
host | 對應的主機地址 | 微服務應用的Ip內網地址 |
port | 端口號 | |
processorTime | CPU使使用率 | |
timeStamp | 注冊時間戳 | |
serviceProtocol | 服務協議 |
時間戳
timeStamp
是指向服務注冊中心更新服務元數據的時間戳。
使用Zookeeper作為服務注冊中心
silky支持使用 Zookeeper 作為服務注冊中心。
silky支持為微服務集群配置多個 Zookeeper 服務注冊中心,您只需要在配置服務注冊中心的鏈接字符串registrycenter.connectionStrings
中,使用分號;
就可以指定微服務框架的多個服務注冊中心。
使用 Zookeeper 作為服務注冊中心需要在配置文件中,在registrycenter
配置節點下,將服務注冊中心的類型type
設置為: Zookeeper
,通過connectionStrings
屬性配置服務中心的鏈接。同時可以通過其他屬性配置服務注冊中心的鏈接屬性。
registrycenter: // 服務注冊中心配置節點
type: Zookeeper
connectionStrings: 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186 // 服務配置中心鏈接
connectionTimeout: 1000 // 鏈接超時時間(單位:ms)
sessionTimeout: 2000 // 會話超時時間(單位:ms)
operatingTimeout: 4000 // 操作超時時間(單位:ms)
routePath: /services/serviceroutes
一般地,使用 Zookeeper 作為服務注冊中心我們只需要指定服務注冊中心類型和鏈接字符串即可,其他屬性(如鏈接超時時間、會話時間、操作超時時間、注冊的路由地址等)均提供了缺省值。
registrycenter: // 服務注冊中心配置節點
type: Zookeeper
connectionStrings: 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186 // 服務配置中心鏈接
silky框架提供了使用 docker-compose 來編排 Zookeeper 的 編排文件, 開發者在獲取 silky源代碼后,進入到 ./samples/docker-compose/infrastr
目錄后,執行如下命令,就可以構建一個 Zookeeper 服務集群。
docker-compose -f docker-compose.zookeeper.yml up -d
使用Nacos作為服務注冊中心
silky支持使用 Nacos 作為服務注冊中心。
如果使用 Nacos 作為服務注冊中心,需要將 registrycenter:type
配置設置為:Nacos
,再加上 Nacos 的其他配置屬性。開發者可以參考Nacos文檔以及nacos-sdk-csharp 來熟悉 Nacos 的配置和使用。
使用 Nacos 作為服務注冊中心的配置如下:
registrycenter:
type: Nacos
namespace: silky
serverAddresses:
- http://127.0.0.1:8848/
- http://127.0.0.1:8849/
- http://127.0.0.1:8850/
userName: nacos
password: nacos
groupName: DEFAULT_GROUP
clusterName: DEFAULT
registerEnabled: true
instanceEnabled: true
namingUseRpc: true
關於 Nacas服務的搭建可以參考Nacos Docker 快速開始。當然, silky框架也提供了使用 docker-compose 來編排 Nacos 服務的文件,開發者在獲取源代碼后,進入到 ./samples/docker-compose/infrastr
目錄后,執行如下命令,就可以構建一個 Nacos 服務集群。
docker-compose -f docker-compose.nacos.cluster-hostname.yaml up -d
使用Consul作為服務注冊中心
silky支持使用 Consul 作為服務注冊中心。
如果使用 Consul 作為服務注冊中心,需要將 registrycenter:type
配置設置為:Consul
,再加上 Consul 的其他配置屬性。開發者可以參考Consul文檔以及consuldotnet 來熟悉 Consul 的配置和使用。
使用 Consul 作為服務注冊中心的配置如下:
registrycenter:
type: Consul
address: http://127.0.0.1:8500
datacenter: dc1 # 缺省值為 dc1
token:"" # 如果consul服務設置了token,則需要配置token
waitTime: 1000 # 缺省值為空
heartBeatInterval: 10 # 缺省值為10,單位為秒
搭建consul服務集群的方式開發者可以參考。同樣地,silky框架提供了使用 docker-compose 部署 Consul 集群的編排文件,開發者在獲取源碼后,進入到 ./samples/docker-compose/infrastr
目錄后,執行如下命令,就可以構建一個 Consul 服務集群。
docker-compose -f docker-compose.consul.yaml up -d
開源地址
- github: https://github.com/liuhll/silky
- gitee: https://gitee.com/liuhll2/silky