Mesh 对接 Nacos 解决方案
本文介绍如何将 Nacos 的服务元数据同步至 dsrconsole,实现 Mesh 对接 Nacos。
背景信息
dsrconsole 作为微服务控制台,需要展示应用以及服务相关信息,以便对这些应用以及服务进行服务治理。例如您需要查询应用列表和服务列表。
Nacos 作为开源的分布式注册中心,存放了服务相关的元数据信息,这些数据需要和 dsrconsole 微服务管控台上看到的服务信息保持一致性和完整性,因此需要以某种方式能够在 dsrconsole 控制台上看到 Nacos 上面存放的服务元数据信息。
实现方案
Nacos 端暴露 REST 接口,提供对应用元数据、服务元数据、服务详情的查询功能。dsrconsole 展示服务目录相关数据时,直接调用 Nacos 提供的接口去查询。实现链路如下:
目前,业务应用是由 MOSN 进行代理注册的,所以整个方案的链路为 nacos-go-client SDK 向 Nacos 进行服务的发布和订阅操作。Nacos 服务端暴露 REST 接口,该接口返回服务的客户端和服务端信息。 用户单击dsrconsole 服务目录或查询服务元数据信息时,查看 Nacos 的新接口并在控制台进行展示。
dsrconsole 改造
原有逻辑是 dsrconsole 中有几张表存储应用、服务信息,查询数据时从数据库提取。改造后,查询数据时直接调用 Nacos 提供的接口进行查询。
在 Controller 层加一个开关,在 Controller 层直接调用 Nacos 提供的接口并返回。
Nacos Server 改造
Nacos 的模型是 service > cluster > instance,应用名存放在 instance 下面。改造后,Nacos 重新维护一份数据模型 App > service。并且最好能够把调用方应用和服务方应用区分开(不维护数据模型,直接提供相应的查询接口)。
操作步骤
Nacos Server 的需要 v1.3.2 及以上版本。
Nacos Go SDK 的需要 v1.0.7 及以上版本。
MOSN GO Client 版本的修改说明请参见 GitHub。
修改
dsrconsole service_info
表索引。您可以参考如下内容修改:
ALTER TABLE `service_info` ADD UNIQUE INDEX `uk_instance_id_data_id_app_name` (`instance_id`, `data_id`(255), `app_name`(255)); drop index `uk_key` on `service_info` ;
设置新增 DRM 配置项,关闭 sofa registry 推送。
新增的 DRM 配置项如下:
域:AntCloud
所属应用:dsrconsole
类标识:
com.alipay.antcloud.dsrconsole.core.service.config.DegradationConfig
新增属性一:processAliveDetectedSwitch 备注(开启进程检查开关)。
新增属性二:syncDegrade 备注(降级开关)。
修改以下属性值:
属性 processAliveDetectedSwitch(是否开启进程检查),推送值:false。
属性 syncDegrade(降级开关),推送值:true。
附录:Nacos 相关接口
查询服务列表
请求类型:GET
请求路径:
/nacos/v1/ns/service/list
请求参数:
名称
类型
是否必选
描述
instanceId
String
是
租户实例 ID
pageNo
int
是
当前页码
pageSize
int
是
分页大小
请求示例:
curl -X GET '127.0.0.1:8848/nacos/v1/ns/service/list?instaceId=000001&pageNo=1&pageSize=2'
返回示例:
{ "count":148, "list": [ { "serviceName": "nacos.test.1@crpc", "pubApp": "crpc-server1" }, { "serviceName": "nacos.test.2@crpc", "pubApp": "crpc-server2" } ] }
查询应用列表
请求类型:GET
请求路径:
/nacos/v1/ns/apps/list
请求参数:
名称
类型
是否必选
描述
instanceId
String
是
租户实例 ID
请求示例:
curl -X GET '127.0.0.1:8848/nacos/v1/ns/apps/list?instanceId=000001
返回示例:
{ "apps": [ "app1", "app2" ] }
查询客户端应用下的服务列表
请求类型:GET
请求路径:
/nacos/v1/ns/services/client/list
请求参数:
名称
类型
是否必选
描述
instanceId
String
是
租户实例 ID
appName
String
是
应用名称
请求示例:
curl -X GET '127.0.0.1:8848/nacos/v1/ns/services/client/list?instanceId=000001&appName=xxx
返回示例:
{ "servers": [ "com.xxx.Facade1", "com.xxx.Facade2" ] }
查询服务端应用下的服务列表
请求类型:GET
请求路径:
/nacos/v1/ns/services/server/list
请求参数:
名称
类型
是否必选
描述
instanceId
String
是
租户实例 ID
appName
String
是
应用名称
groupName
String
否
分组名
namespaceId
String
否
命名空间 ID
请求示例:
curl -X GET '127.0.0.1:8848/nacos/v1/ns/services/server/list?instanceId=000001&appName=xxx
返回示例:
{ "servers": [ "com.xxx.Facade1", "com.xxx.Facade2" ] }
查询服务提供者详情
请求类型:GET
请求路径:
/nacos/v1/ns/services/serverpub/detail/list
请求参数:
名称
类型
是否必选
描述
instanceId
String
是
租户实例 ID
serverName
String
是
服务名称
groupName
String
否
分组名
namespaceId
String
否
命名空间 ID
请求示例:
curl -X GET '127.0.0.1:8848/nacos/v1/ns/services/serverpub/detail/list?instanceId=000001&serverName=com.xxx.Facade1@crpc
返回示例:
{ "serverPubDetails": [ { "serverName": "com.xxx.Facade1@crpc", "metadata": `crpc://30.**.**.89:30778?VMMODE=true&annotations={"serviceName":"org.example.services.userInterface.UserService:1.0.0:default@crpc","protocol":"crpc","targetPort":9999,"healthCheckConfig":{"timeout":10,"interval":10,"intervalJitter":2,"firstHealthyDelay":15,"healthyThreshold":3,"unhealthyThreshold":2,"commonCallbacks":["confregWithDelayOnce"],"http":{}}}&app.kubernetes.io/version=1.2&appName=crpc-server&datacenter=dc1&mosn=true&port=9999&pressure_test=false&tls=false&zone=GZ00T` }, { "serverName": "com.xxx.Facade2@crpc", "metadata": `crpc://30.**.**.89:30778?VMMODE=true&annotations={"serviceName":"org.example.services.userInterface.UserService:1.0.0:default@crpc","protocol":"crpc","targetPort":9999,"healthCheckConfig":{"timeout":10,"interval":10,"intervalJitter":2,"firstHealthyDelay":15,"healthyThreshold":3,"unhealthyThreshold":2,"commonCallbacks":["confregWithDelayOnce"],"http":{}}}&app.kubernetes.io/version=1.2&appName=crpc-server&datacenter=dc1&mosn=true&port=9999&pressure_test=false&tls=false&zone=GZ00T` } ] }
查询服务订阅者详情
请求类型:GET
请求路径:
/nacos/v1/ns/services/serversub/detail/list
请求参数:
名称
类型
是否必选
描述
instanceId
String
是
租户实例ID
serverName
String
是
服务名称
groupName
String
否
分组名
namespaceId
String
否
命名空间ID
请求示例:
curl -X GET '127.0.0.1:8848/nacos/v1/ns/services/serversub/detail/list?instanceId=000001&serverName=com.xxx.Facade1@crpc
返回示例:
{ "serverPubDetails": [ { "serverName": "com.xxx.Facade1@crpc", "ip": "30.**.**.31", "appName": "crpc-client" }, { "serverName": "com.xxx.Facade2@crpc", "ip": "30.**.**.32", "appName": "crpc-client" } ] }