Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nacos server] /beat 接收nacos客户端心跳返回的 clientBeatInterval 一直是客户端上报的值,nacos server 更改无效 #3353

Closed
pengyusong opened this issue Jul 16, 2020 · 3 comments
Labels
area/Naming good first issue Good for newcomers kind/enhancement Category issues or prs related to enhancement.
Milestone

Comments

@pengyusong
Copy link

开启了nacos server 和client的debug日志,发现客户端心跳一直是以客户端配置的心跳间隔值,服务器端的clientBeatInterval配置没有生效。

查看源码,发现以下代码的最后四行,将返回的clientBeatInterval字段强制更新为客户端上报的心跳间隔值,导致服务器无法动态调整客户端的心跳间隔:

    public ObjectNode beat(HttpServletRequest request) throws Exception {
        
        ObjectNode result = JacksonUtils.createEmptyJsonNode();
        result.put("clientBeatInterval", switchDomain.getClientBeatInterval());
        
        String beat = WebUtils.optional(request, "beat", StringUtils.EMPTY);
        RsInfo clientBeat = null;
        if (StringUtils.isNotBlank(beat)) {
            clientBeat = JacksonUtils.toObj(beat, RsInfo.class);
        }
        String clusterName = WebUtils
                .optional(request, CommonParams.CLUSTER_NAME, UtilsAndCommons.DEFAULT_CLUSTER_NAME);
        String ip = WebUtils.optional(request, "ip", StringUtils.EMPTY);
        int port = Integer.parseInt(WebUtils.optional(request, "port", "0"));
        if (clientBeat != null) {
            if (StringUtils.isNotBlank(clientBeat.getCluster())) {
                clusterName = clientBeat.getCluster();
            } else {
                // fix #2533
                clientBeat.setCluster(clusterName);
            }
            ip = clientBeat.getIp();
            port = clientBeat.getPort();
        }
        String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
        String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
        Loggers.SRV_LOG.debug("[CLIENT-BEAT] full arguments: beat: {}, serviceName: {}", clientBeat, serviceName);
        Instance instance = serviceManager.getInstance(namespaceId, serviceName, clusterName, ip, port);
        
        if (instance == null) {
            if (clientBeat == null) {
                result.put(CommonParams.CODE, NamingResponseCode.RESOURCE_NOT_FOUND);
                return result;
            }
            
            Loggers.SRV_LOG.warn("[CLIENT-BEAT] The instance has been removed for health mechanism, "
                    + "perform data compensation operations, beat: {}, serviceName: {}", clientBeat, serviceName);
            
            instance = new Instance();
            instance.setPort(clientBeat.getPort());
            instance.setIp(clientBeat.getIp());
            instance.setWeight(clientBeat.getWeight());
            instance.setMetadata(clientBeat.getMetadata());
            instance.setClusterName(clusterName);
            instance.setServiceName(serviceName);
            instance.setInstanceId(instance.getInstanceId());
            instance.setEphemeral(clientBeat.isEphemeral());
            
            serviceManager.registerInstance(namespaceId, serviceName, instance);
        }
        
        Service service = serviceManager.getService(namespaceId, serviceName);
        
        if (service == null) {
            throw new NacosException(NacosException.SERVER_ERROR,
                    "service not found: " + serviceName + "@" + namespaceId);
        }
        if (clientBeat == null) {
            clientBeat = new RsInfo();
            clientBeat.setIp(ip);
            clientBeat.setPort(port);
            clientBeat.setCluster(clusterName);
        }
        service.processClientBeat(clientBeat);
        
        result.put(CommonParams.CODE, NamingResponseCode.OK);
        result.put("clientBeatInterval", instance.getInstanceHeartBeatInterval());
        result.put(SwitchEntry.LIGHT_BEAT_ENABLED, switchDomain.isLightBeatEnabled());
        return result;
    }
@KomachiSion
Copy link
Collaborator

这个逻辑的确有点冲突,但是并不是无法修改,只不过修改的是这个instance的metadata,在这个服务实例下,修改其metadata,添加key preserved.heart.beat.interval, 值单位为毫秒。 就可以控制这个实例的上报间隔。

这里确实需要优化一下逻辑,因为相当于全局设置是失效的。

@KomachiSion KomachiSion added kind/enhancement Category issues or prs related to enhancement. area/Naming good first issue Good for newcomers labels Jul 17, 2020
@KomachiSion KomachiSion added this to the 1.3.2 milestone Jul 17, 2020
@zongtanghu
Copy link
Collaborator

Can you help to resolve this issue? @wangweizZZ

@wangweizZZ
Copy link
Collaborator

ok. i will resolve it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/Naming good first issue Good for newcomers kind/enhancement Category issues or prs related to enhancement.
Projects
None yet
Development

No branches or pull requests

4 participants