配置管理-监听查询-通过IP维度无法查询监听信息
在配置管理-监听查询-通过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接口不合理
新版本通过页面字段约束,已经没有这个问题了。
新版本通过页面字段约束,已经没有这个问题了。
我描述是:查询维度是 IP 时候的问题,不是维度是配置的问题
Anyone in community interesting this issue?
Anyone in community interesting this issue?
@i will solve it@
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;
}
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")感觉这两个接口合并一下更合理些
不要动底层的两个原子接口,configWatchers和watcherConfigs不要动
两个方案:
-
简单处理,可以在ClusterListenerJob 拼装url的时候做下处理, static class ClusterListenerJob extends ClusterJob<SampleResult> {
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。
-
在ClusterJob层做区分 新增ClusterListenerByIpJob static class ClusterListenerByIpJob extends ClusterJob<SampleResult> {
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<SampleResult> runConfigListenerByIpCollectionJob(Map<String, String> params, CompletionService<SampleResult> 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")感觉这两个接口合并一下更合理些
接口不建议合并,底层原子接口保持语义清晰
"/watcherConfigs""/configWatchers",ip作为检索数据的一个选项,应该是接口中的一个参数而已,现有的这两个接口从定义上就很让人疑惑。我现在的做法是增加新的接口@GetMapping("/config"),传参中通过一个查询类型是ip还是config去执行不同逻辑。
"/watcherConfigs""/configWatchers"这两个接口的具体实现我并没有动,但我标注了@Deprecated
"/watcherConfigs""/configWatchers",ip作为检索数据的一个选项,应该是接口中的一个参数而已,现有的这两个接口从定义上就很让人疑惑。我现在的做法是增加新的接口@GetMapping("/config"),传参中通过一个查询类型是ip还是config去执行不同逻辑。
"/watcherConfigs""/configWatchers"这两个接口的具体实现我并没有动,但我标注了@deprecated
复用原来的接口吧,不要加新接口了

