nacos发送beat逻辑

服务注册 registerInstance

服务注册的时候,如果实例是临时的(ephemeral=true),则会构造发送心跳包

NacosNamingService.registerInstance

public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
        String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
        if (instance.isEphemeral()) { // 临时的
            BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
            beatReactor.addBeatInfo(groupedServiceName, beatInfo); // /nacos/v1/ns/instance/beat发送心跳
        } // addBeatInfo: /nacos/v1/ns/instance/beat?app=unknown&serviceName=DEFAULT_GROUP%40%40nacos-discovery&namespaceId=public&port=8082&clusterName=DEFAULT&ip=169.254.104.253
        serverProxy.registerService(groupedServiceName, groupName, instance);
    }


BeatReactor

用于向Nacos服务端发送已注册服务心跳

默认5s执行一次心跳

public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
        NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo);
        String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort());
        BeatInfo existBeat = null;
        //fix #1733
        if ((existBeat = dom2Beat.remove(key)) != null) {
            existBeat.setStopped(true);
        }
        dom2Beat.put(key, beatInfo);
        executorService.schedule(new BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS); // period毫秒后执行1次 默认5s
        MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
    }

BeatTask

如果服务器返回404,则会向服务器重新注册实例

默认5s执行一次心跳

class BeatTask implements Runnable {

	BeatInfo beatInfo;

	public BeatTask(BeatInfo beatInfo) {
		this.beatInfo = beatInfo;
	}

	@Override
	public void run() {
		if (beatInfo.isStopped()) {
			return;
		}
		long nextTime = beatInfo.getPeriod(); //period
		try {
			JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled); // 发送心跳包 PUT /nacos/v1/ns/instance/beat
			long interval = result.get("clientBeatInterval").asLong();
			boolean lightBeatEnabled = false;
			if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) {
				lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean();
			}
			BeatReactor.this.lightBeatEnabled = lightBeatEnabled;
			if (interval > 0) {
				nextTime = interval;
			}
			int code = NamingResponseCode.OK;
			if (result.has(CommonParams.CODE)) {
				code = result.get(CommonParams.CODE).asInt();
			}
			if (code == NamingResponseCode.RESOURCE_NOT_FOUND) { // 没找到资源
				Instance instance = new Instance();
				instance.setPort(beatInfo.getPort());
				instance.setIp(beatInfo.getIp());
				instance.setWeight(beatInfo.getWeight());
				instance.setMetadata(beatInfo.getMetadata());
				instance.setClusterName(beatInfo.getCluster());
				instance.setServiceName(beatInfo.getServiceName());
				instance.setInstanceId(instance.getInstanceId());
				instance.setEphemeral(true);
				try {
					serverProxy.registerService(beatInfo.getServiceName(),
							NamingUtils.getGroupName(beatInfo.getServiceName()), instance); // 重新向服务器注册实例
				} catch (Exception ignore) {
				}
			}
		} catch (NacosException ex) {
			NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: {}, code: {}, msg: {}",
					JacksonUtils.toJson(beatInfo), ex.getErrCode(), ex.getErrMsg());

		}
		executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS); // 设置下一次执行  nextTime(period)毫秒后执行1次 默认5s
	}
}

猜你喜欢

转载自blog.csdn.net/kq1983/article/details/113350906