开发者社区> 问答> 正文

nacos客户端心跳问题

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

开启了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;
}

展开
收起
一人吃饱,全家不饿 2021-02-01 22:54:49 2025 0
来自:阿里开源
1 条回答
写回答
取消 提交回答
  • 这个逻辑的确有点冲突,但是并不是无法修改,只不过修改的是这个instance的metadata,在这个服务实例下,修改其metadata,添加key preserved.heart.beat.interval, 值单位为毫秒。 就可以控制这个实例的上报间隔。

    2021-02-01 22:55:02
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
来源圈子
更多
收录在圈子:
+ 订阅
阿里巴巴相信开源的世界里人人贡献代码,人人获得收益,共同创造一个互帮互利的社区,促进技术进步和发展。
问答排行榜
最热
最新

相关电子书

更多
Nacos架构&原理 立即下载
workshop专场-微服务专场-开发者动手实践营-微服务-使用Nacos进行服务的动态发现和流量调度 立即下载
Nacos 启航,发布第一个版本, 云原生时代助力用户微服务平台建设 立即下载