Nacos指南-服务发现:CMDB功能解析

上文分析创建服务时,我们发现有个访问策略的参数,下面我们就一起探索一下访问策略怎么玩的

名称类型是否必选描述
selectorJSON格式字符串访问策略

在Nacos控制台上对应的配置名称为服务路由类型。除了默认值之外还可以选择标签类型,通过上文分析selector的格式为:

{"type": "label","expression": "CONSUMER.label.myLabel=PROVIDER.label.myLabel"}

在这里插入图片描述

若选择标签模式,表达式可以使用如下格式填写(必须以"CONSUMER.label."开始):
例:

CONSUMER.label.region=PROVIDER.label.region

此处我使用 region 作为标签。

CMDB_DATA_TABLE

ipregion
10.10.10.10shanghai
11.11.11.11shanghai
20.20.20.20beijing
21.21.21.21beijing

可以看出来
ip为 10.10.10.10,11.11.11.11 的归属地是上海
ip为 20.20.20.20,21.21.21.21 的归属地是北京

如果我们此时在上海,同城网络请求的耗时假设10ms,若访问北京服务器网络耗时假设30ms。若是我们在微服务调用的时候,同城网络只调用同城服务器是否就大大的提高了网络请求的效率?

先直接上结果:

先注册4个实例

curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?port=8848&healthy=true&ip=10.10.10.10&weight=1.0&serviceName=spring-cloud-demo&encoding=GBK'curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?port=8848&healthy=true&ip=11.11.11.11&weight=1.0&serviceName=spring-cloud-demo&encoding=GBK'curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?port=8848&healthy=true&ip=20.20.20.20&weight=1.0&serviceName=spring-cloud-demo&encoding=GBK'curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?port=8848&healthy=true&ip=21.21.21.21&weight=1.0&serviceName=spring-cloud-demo&encoding=GBK'

此时服务名为spring-cloud-demo的4个实例已经全部注册成功

在这里插入图片描述

此时请求实例列表

curl -X GET '127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=spring-cloud-demo'

返回的数据为:

{"hosts": [{"ip": "21.21.21.21","port": 8848,"valid": true,"healthy": true,"marked": false,"instanceId": "21.21.21.21#8848#DEFAULT#DEFAULT_GROUP@@spring-cloud-demo","metadata": {},"enabled": true,"weight": 1.0,"clusterName": "DEFAULT","serviceName": "spring-cloud-demo","ephemeral": true},{"ip": "20.20.20.20","port": 8848,"valid": true,"healthy": true,"marked": false,"instanceId": "20.20.20.20#8848#DEFAULT#DEFAULT_GROUP@@spring-cloud-demo","metadata": {},"enabled": true,"weight": 1.0,"clusterName": "DEFAULT","serviceName": "spring-cloud-demo","ephemeral": true},{"ip": "10.10.10.10","port": 8848,"valid": true,"healthy": true,"marked": false,"instanceId": "10.10.10.10#8848#DEFAULT#DEFAULT_GROUP@@spring-cloud-demo","metadata": {},"enabled": true,"weight": 1.0,"clusterName": "DEFAULT","serviceName": "spring-cloud-demo","ephemeral": true},{"ip": "11.11.11.11","port": 8848,"valid": true,"healthy": true,"marked": false,"instanceId": "11.11.11.11#8848#DEFAULT#DEFAULT_GROUP@@spring-cloud-demo","metadata": {},"enabled": true,"weight": 1.0,"clusterName": "DEFAULT","serviceName": "spring-cloud-demo","ephemeral": true}],"dom": "spring-cloud-demo","name": "DEFAULT_GROUP@@spring-cloud-demo","cacheMillis": 3000,"lastRefTime": 1619072167699,"checksum": "c1230e0a77527f4093389636e4f85ccf","useSpecifiedURL": false,"clusters": "","env": "","metadata": {}
}

我们知道,我们的客户端实例在获取所属服务列表的时候会将自身ip传入clientIP请求参数中(此处详见NamingProxy.queryList)

    public String queryList(String serviceName, String clusters, int udpPort, boolean healthyOnly) throws NacosException {Map<String, String> params = new HashMap(8);params.put("namespaceId", this.namespaceId);params.put("serviceName", serviceName);params.put("clusters", clusters);params.put("udpPort", String.valueOf(udpPort));//传入当前实例的ip地址params.put("clientIP", NetUtils.localIP());params.put("healthyOnly", String.valueOf(healthyOnly));return this.reqApi(UtilAndComs.nacosUrlBase + "/instance/list", params, "GET");}

下面我们模拟实例端10.10.10.10请求服务列表

curl -X GET '127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=spring-cloud-demo&clientIP=10.10.10.10'

返回的数据为:

{"hosts": [{"ip": "10.10.10.10","port": 8848,"valid": true,"healthy": true,"marked": false,"instanceId": "10.10.10.10#8848#DEFAULT#DEFAULT_GROUP@@spring-cloud-demo","metadata": {},"enabled": true,"weight": 1.0,"clusterName": "DEFAULT","serviceName": "spring-cloud-demo","ephemeral": true},{"ip": "11.11.11.11","port": 8848,"valid": true,"healthy": true,"marked": false,"instanceId": "11.11.11.11#8848#DEFAULT#DEFAULT_GROUP@@spring-cloud-demo","metadata": {},"enabled": true,"weight": 1.0,"clusterName": "DEFAULT","serviceName": "spring-cloud-demo","ephemeral": true}],"dom": "spring-cloud-demo","name": "DEFAULT_GROUP@@spring-cloud-demo","cacheMillis": 3000,"lastRefTime": 1619072800221,"checksum": "c1230e0a77527f4093389636e4f85ccf","useSpecifiedURL": false,"clusters": "","env": "","metadata": {}
}

以上已经实现了服务路由标签过滤。若未匹配到标签,则默认返回全部提供方。

看一下实现

首先实现com.alibaba.nacos.api.cmdb.spi.CmdbService接口,将自己的cmdb数据转化成nacos的数据格式。

public class MyCmdbServiceImpl implements CmdbService {public static final List<Map<String,String>> CMDB_DATA =new ArrayList<>();{/*  CMDB_DATA_TABLE:模拟cmdb数据库数据*  ip          region*  10.10.10.10     shanghai*  11.11.11.11     shanghai*  20.20.20.20    beijing*  21.21.21.21     beijing*/Map<String,String> machine10=new HashMap<>();machine10.put("ip","10.10.10.10");machine10.put("region","shanghai");CMDB_DATA.add(machine10);Map<String,String> machine11=new HashMap<>();machine11.put("ip","11.11.11.11");machine11.put("region","shanghai");CMDB_DATA.add(machine11);Map<String,String> machine20=new HashMap<>();machine20.put("ip","20.20.20.20");machine20.put("region","beijing");CMDB_DATA.add(machine20);Map<String,String> machine21=new HashMap<>();machine21.put("ip","21.21.21.21");machine21.put("region","beijing");CMDB_DATA.add(machine21);}@Overridepublic Set<String> getLabelNames() {return parseKeySet();}private Set<String> parseKeySet(){Set<String> labelNames=new HashSet<>();CMDB_DATA.forEach(d->{labelNames.addAll(d.keySet());});return labelNames;}@Overridepublic Set<String> getEntityTypes() {return parseKeySet();}@Overridepublic Label getLabel(String labelName) {Label label=new Label();label.setName(labelName);label.setValues(new HashSet<>());CMDB_DATA.forEach(d->{label.getValues().add(d.get(labelName));});return label;}@Overridepublic String getLabelValue(String entityName, String entityType, String labelName) {return getEntity(entityName,entityType).getLabels().get(labelName);}@Overridepublic Map<String, String> getLabelValues(String entityName, String entityType) {return getEntity(entityName,entityType).getLabels();}@Overridepublic Map<String, Map<String, Entity>> getAllEntities() {Map<String, Map<String, Entity>> result=new HashMap<>();CMDB_DATA.forEach(d->{d.keySet().forEach(col->{if(!result.containsKey(col)){result.put(col,new HashMap<>());}Entity entity=new Entity();entity.setName(d.get(col));entity.setType(col);entity.setLabels(d);result.get(col).put(d.get(col),entity);});});return result;}@Overridepublic List<EntityEvent> getEntityEvents(long timestamp) {//此处是cmdb数据变更事件的实现,由于是模拟,所有没有实现。return null;}@Overridepublic Entity getEntity(String entityName, String entityType) {Map<String, Map<String, Entity>> allEntities = getAllEntities();return allEntities.get(entityType).get(entityName);}
}

开启Cmdb加载参数

nacos.cmdb.loadDataAtStart=true

将我们自己的实现引入Nacos,通过SPI机制加载。

在 resources/META-INF/services 目录下创建名为 com.alibaba.nacos.api.cmdb.spi.CmdbService 的文件,文件内容为实现类的全路径:com.alibaba.nacos.cmdb.spi.MyCmdbServiceImpl (此处是我本次实现的类路径,自己实现需要根据实际情况)。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部