nacos 配置管理-监听查询-通过IP维度无法查询监听信息

6ioyuze2  于 5个月前  发布在  Nacos
关注(0)|答案(9)|浏览(128)

在配置管理-监听查询-通过IP维度查询监听列表时,请求的接口是 nacos/v1/cs/listener?ip=xxxx$tenant=xxx

此接口位于 com.alibaba.nacos.config.server.controller.ListenerController#getAllSubClientConfigByIp() ,调用了 com.alibaba.nacos.config.server.service.ConfigSubService#getCollectSampleResultByIp() 方法,在方法内调用 runConfigListenerCollectionJob() ,最终在 runSingleJob() 方法内发送了一个resttemplate请求,请求的接口是 /nacos/v1/cs/communication/configWatchers?&ip=xxx ,参数只有 ip 。次接口位于 com.alibaba.nacos.config.server.controller.CommunicationController ,代码如下,其中dataId和group为必输,因此前面发送的resttemplate请求与接口不匹配,会直接报错。

@GetMapping("/configWatchers")
public SampleResult getSubClientConfig(@RequestParam("dataId") String dataId, @RequestParam("group") String group,
        @RequestParam(value = "tenant", required = false) String tenant, ModelMap modelMap) {
    group = StringUtils.isBlank(group) ? Constants.DEFAULT_GROUP : group;
    // long polling listeners.
    SampleResult result = longPollingService.getCollectSubscribleInfo(dataId, group, tenant);
    // rpc listeners.
    String groupKey = GroupKey2.getKey(dataId, group, tenant);
    Set<String> listenersClients = configChangeListenContext.getListeners(groupKey);
    if (CollectionUtils.isEmpty(listenersClients)) {
        return result;
    }
    Map<String, String> listenersGroupkeyStatus = new HashMap<>(listenersClients.size(), 1);
    for (String connectionId : listenersClients) {
        Connection client = connectionManager.getConnection(connectionId);
        if (client != null) {
            String md5 = configChangeListenContext.getListenKeyMd5(connectionId, groupKey);
            if (md5 != null) {
                listenersGroupkeyStatus.put(client.getMetaInfo().getClientIp(), md5);
            }
        }
    }
    result.getLisentersGroupkeyStatus().putAll(listenersGroupkeyStatus);
    return result;
}

需要请求参数附带dataId、group和tenant参数,请求进入到此接口,才能查询到监听信息
例如请求地址为:
http://127.0.0.1:8848/nacos/v1/cs/communication/configWatchers?ip=192.168.137.1&dataId=nacos-config-extend.yaml&group=DEFAULT_GROUP&tenant=dc9c503f-048e-4cad-925c-b85d359fd9ed
响应信息为:

{
  "lisentersGroupkeyStatus": {
    "192.168.137.1": "57f84e31750c96a8e78e35d97e79303b"
  }
}

但是这个请求的本质是通过IP查询监听信息,因此这个controller接口不合理

8oomwypt

8oomwypt1#

新版本通过页面字段约束,已经没有这个问题了。

zhte4eai

zhte4eai2#

新版本通过页面字段约束,已经没有这个问题了。

我描述是:查询维度是 IP 时候的问题,不是维度是配置的问题

6pp0gazn

6pp0gazn3#

Anyone in community interesting this issue?

db2dz4w8

db2dz4w84#

Anyone in community interesting this issue?

@i will solve it@

ffscu2ro

ffscu2ro5#

Anyone in community interesting this issue?

现在是有接口的,只是在调用的时候url错了,只有一个url,重新封装一下 ClusterListenerJob 就好了

接口代码

/**
     * Get client config listener lists of subscriber in local machine.
     */
    @GetMapping("/watcherConfigs")
    public SampleResult getSubClientConfigByIp(HttpServletRequest request, HttpServletResponse response,
            @RequestParam("ip") String ip, ModelMap modelMap) {
        
        SampleResult result = longPollingService.getCollectSubscribleInfoByIp(ip);
        List<Connection> connectionsByIp = connectionManager.getConnectionByIp(ip);
        for (Connection connectionByIp : connectionsByIp) {
            Map<String, String> listenKeys = configChangeListenContext
                    .getListenKeys(connectionByIp.getMetaInfo().getConnectionId());
            if (listenKeys != null) {
                result.getLisentersGroupkeyStatus().putAll(listenKeys);
            }
        }
        return result;
        
    }
fnx2tebb

fnx2tebb6#

Anyone in community interesting this issue?

现在是有接口的,只是在调用的时候url错了,只有一个url,重新封装一下 ClusterListenerJob 就好了

接口代码

/**
     * Get client config listener lists of subscriber in local machine.
     */
    @GetMapping("/watcherConfigs")
    public SampleResult getSubClientConfigByIp(HttpServletRequest request, HttpServletResponse response,
            @RequestParam("ip") String ip, ModelMap modelMap) {
        
        SampleResult result = longPollingService.getCollectSubscribleInfoByIp(ip);
        List<Connection> connectionsByIp = connectionManager.getConnectionByIp(ip);
        for (Connection connectionByIp : connectionsByIp) {
            Map<String, String> listenKeys = configChangeListenContext
                    .getListenKeys(connectionByIp.getMetaInfo().getConnectionId());
            if (listenKeys != null) {
                result.getLisentersGroupkeyStatus().putAll(listenKeys);
            }
        }
        return result;
        
    }

@GetMapping("/watcherConfigs")@GetMapping("/configWatchers")感觉这两个接口合并一下更合理些

ugmeyewa

ugmeyewa7#

不要动底层的两个原子接口,configWatchers和watcherConfigs不要动

两个方案:

  1. 简单处理,可以在ClusterListenerJob 拼装url的时候做下处理,
    static class ClusterListenerJob extends ClusterJob {
static final String URL = Constants.COMMUNICATION_CONTROLLER_PATH + "/configWatchers";
 static final String URL = Constants.COMMUNICATION_CONTROLLER_PATH + "/watcherConfigs";

 
 ClusterListenerJob(Map<String, String> params, CompletionService<SampleResult> completionService,
         ServerMemberManager serverMemberManager) {
     super(URL, params, completionService, serverMemberManager);
 }

}
如果参数中包含ip地址,就调用watcherConfigs,包含dataId和group时调用configWatchers。

  1. 在ClusterJob层做区分
    新增ClusterListenerByIpJob
    static class ClusterListenerByIpJob extends ClusterJob {
static final String URL = Constants.COMMUNICATION_CONTROLLER_PATH + "/watcherConfigs";

 ClusterListenerByIpJob(Map<String, String> params, CompletionService<SampleResult> completionService,
         ServerMemberManager serverMemberManager) {
     super(URL, params, completionService, serverMemberManager);
 }

}

新增
private List runConfigListenerByIpCollectionJob(Map<String, String> params,
CompletionService completionService) {
return new ClusterListenerByIpJob(params, completionService, memberManager).runJobs();
}
Anyone in community interesting this issue?

现在是有接口的,只是在调用的时候url错了,只有一个url,重新封装一下 ClusterListenerJob 就好了
接口代码

/**
     * Get client config listener lists of subscriber in local machine.
     */
    @GetMapping("/watcherConfigs")
    public SampleResult getSubClientConfigByIp(HttpServletRequest request, HttpServletResponse response,
            @RequestParam("ip") String ip, ModelMap modelMap) {
        
        SampleResult result = longPollingService.getCollectSubscribleInfoByIp(ip);
        List<Connection> connectionsByIp = connectionManager.getConnectionByIp(ip);
        for (Connection connectionByIp : connectionsByIp) {
            Map<String, String> listenKeys = configChangeListenContext
                    .getListenKeys(connectionByIp.getMetaInfo().getConnectionId());
            if (listenKeys != null) {
                result.getLisentersGroupkeyStatus().putAll(listenKeys);
            }
        }
        return result;
        
    }

@GetMapping("/watcherConfigs")@GetMapping("/configWatchers")感觉这两个接口合并一下更合理些

接口不建议合并,底层原子接口保持语义清晰

crcmnpdw

crcmnpdw8#

"/watcherConfigs""/configWatchers",ip作为检索数据的一个选项,应该是接口中的一个参数而已,现有的这两个接口从定义上就很让人疑惑。我现在的做法是增加新的接口@GetMapping("/config"),传参中通过一个查询类型是ip还是config去执行不同逻辑。

"/watcherConfigs""/configWatchers"这两个接口的具体实现我并没有动,但我标注了@deprecated

kxxlusnw

kxxlusnw9#

"/watcherConfigs""/configWatchers",ip作为检索数据的一个选项,应该是接口中的一个参数而已,现有的这两个接口从定义上就很让人疑惑。我现在的做法是增加新的接口@GetMapping("/config"),传参中通过一个查询类型是ip还是config去执行不同逻辑。

"/watcherConfigs""/configWatchers"这两个接口的具体实现我并没有动,但我标注了@deprecated

复用原来的接口吧,不要加新接口了

相关问题