alibaba / nacos

an easy-to-use dynamic service discovery, configuration and service management platform for building cloud native applications.
https://nacos.io
Apache License 2.0
29.84k stars 12.75k forks source link

Nacos 2.1.1, trying to use cmdb feature to implement calling service closely #9574

Open CFiora opened 1 year ago

CFiora commented 1 year ago

Hello, I'm trying to use cmdb feature to implement calling service closely when there are many provider service instances. I deployed one consumer service and one provider service on my local machine. And I deployed another provider service on remote server. I've putted cmdb plugin in the directory of {nacos.home}/plugins/cmdb and restart the service. I edited the registered provider service (Screenshot below) However, when I used consumer service to call provider service, I expeted only local provider service can be called. But remote provider service was called as well. So, selector of label did not work.

Environment and variables: Nacos server: 2.1.1 Consumer: IP: 10.114.200.154 cluster:cluster1 Local Provider: IP: 10.114.200.154 cluster:cluster1 Remote Provider: IP: 10.114.10.218, cluster:cluster2

Here are my source code below: Provider: Project structure

image

@SpringBootApplication @EnableNacosDiscovery public class ProviderApplication { @NacosInjected private NamingService namingService; @Value("${spring.application.name}") private String springApplicationName; @Value("${nacos.cmdb.ip}") private String nacosCmdbIp; @Value("${nacos.cmdb.port}") private int nacosCmdbPort;

public static void main(String[] args) {
    SpringApplication.run(ProviderApplication.class, args);
}

@PostConstruct
public void registerInstance() throws NacosException {
    namingService.registerInstance(springApplicationName, nacosCmdbIp, nacosCmdbPort);
}

}

@RestController public class ProviderController { @Value("${nacos.cmdb.ip}") private String nacosCmdbIp; @Value("${nacos.cmdb.cluster}") private String nacosCmdbCluster;

@GetMapping("/info")
public String info(String fromCluster, String fromIp) {
    return String.format("Calling from ip %s, cluster %s. Provided from ip %s, cluster %s",
            fromIp, fromCluster, nacosCmdbIp, nacosCmdbCluster);
}

}

Consumer: Project structure

image

@SpringBootApplication @EnableNacosDiscovery public class ConsumerApplication { @NacosInjected private NamingService namingService; @Value("${spring.application.name}") private String springApplicationName; @Value("${nacos.cmdb.ip}") private String nacosCmdbIp; @Value("${nacos.cmdb.port}") private int nacosCmdbPort;

public static void main(String[] args) {
    SpringApplication.run(ConsumerApplication.class, args);
}

@PostConstruct
public void registerInstance() throws NacosException {
    namingService.registerInstance(springApplicationName, nacosCmdbIp, nacosCmdbPort);
}

}

@RestController public class ConsumerController { public static final String ERROR = "Error"; @Value("${service.todo-service}") // provider service name private String todoService; @Value("${nacos.cmdb.ip}") private String nacosCmdbIp; @Value("${nacos.cmdb.cluster}") private String nacosCmdbCluster; @Resource private RestTemplate restTemplate; @NacosInjected private NamingService namingService;

@GetMapping("/getInfo")
public String getInfo() {
    try {
        Instance instance = namingService.selectOneHealthyInstance(todoService);
        String url = String.format("http://%s:%s/info?fromIp=%s&fromCluster=%s",
                instance.getIp(), instance.getPort(), nacosCmdbIp, nacosCmdbCluster);
        return restTemplate.getForObject(url, String.class);
    } catch (NacosException e) {
        return "Error getting instance of " + todoService;
    }
}

}

CMDB plugin public class MyCmdbServiceImpl implements CmdbService { public static final List<Map<String,String>> CMDB_DATA =new ArrayList<>();

{
    /*  CMDB_DATA_TABLE:模拟cmdb数据库数据
     *  ip          region
     *  10.114.200.154     cluster1 local
     *  10.114.10.218      cluster2
     */
    Map<String,String> machine10=new HashMap<>();
    machine10.put("ip","10.114.200.154");
    machine10.put("cluster","cluster1");
    CMDB_DATA.add(machine10);

    Map<String,String> machine11=new HashMap<>();
    machine11.put("ip","10.114.10.218");
    machine11.put("cluster","cluster2");
    CMDB_DATA.add(machine11);

}

@Override
public Set<String> getLabelNames() {
    return parseKeySet();
}

private Set<String> parseKeySet(){
    Set<String> labelNames=new HashSet<>();
    CMDB_DATA.forEach(d->{
        labelNames.addAll(d.keySet());
    });
    return labelNames;
}

@Override
public Set<String> getEntityTypes() {
    return parseKeySet();
}

@Override
public 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;
}

@Override
public String getLabelValue(String entityName, String entityType, String labelName) {
    return getEntity(entityName,entityType).getLabels().get(labelName);
}

@Override
public Map<String, String> getLabelValues(String entityName, String entityType) {
    return getEntity(entityName,entityType).getLabels();
}

@Override
public 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;
}

@Override
public List<EntityEvent> getEntityEvents(long timestamp) {
    return null;
}

@Override
public Entity getEntity(String entityName, String entityType) {
    Map<String, Map<String, Entity>> allEntities = getAllEntities();
    return allEntities.get(entityType).get(entityName);
}

}

image

I've tried calling consumer api and made a summery below. Total:10 Cluster1 Cluster2 Error 5 5 0 50.00 50.00 0.00

I wrote the code with demo on the Internet. Would anyone please point out which part I've done wrong?

CFiora commented 1 year ago

Does anyone have any idea or any example of closed visit ?