4 nacos 注册中心之客户端服务注册
register()方法
Nacos 的服务注册核心方法是 NacosServiceRegistry 的 register 方法:
public void register(Registration registration) {
if (StringUtils.isEmpty(registration.getServiceId())) {
log.warn("No service to register for nacos client...");
} else {
String serviceId = registration.getServiceId();
String group = this.nacosDiscoveryProperties.getGroup();
Instance instance = this.getNacosInstanceFromRegistration(registration);
try {
this.namingService.registerInstance(serviceId, group, instance);
log.info("nacos registry, {} {} {}:{} register finished", new Object[]{group, serviceId, instance.getIp(), instance.getPort()});
} catch (Exception var6) {
log.error("nacos registry, {} register failed...{},", new Object[]{serviceId, registration.toString(), var6});
ReflectionUtils.rethrowRuntimeException(var6);
}
}
}
复制代码
首先判断对应的 ServiceId 是否为空,不为空的话获取 serviceId、group 和 instance,然后我们在方法中调用 Nacos Client 的 registerInstance 完成服务的注册,下面我们看一下 registerInstance()方法的实现
registerInstance()方法:
@Override
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
if (instance.isEphemeral()) {
BeatInfo beatInfo = new BeatInfo();
beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));
beatInfo.setIp(instance.getIp());
beatInfo.setPort(instance.getPort());
beatInfo.setCluster(instance.getClusterName());
beatInfo.setWeight(instance.getWeight());
beatInfo.setMetadata(instance.getMetadata());
beatInfo.setScheduled(false);
long instanceInterval = instance.getInstanceHeartBeatInterval();
beatInfo.setPeriod(instanceInterval == 0 ? DEFAULT_HEART_BEAT_INTERVAL : instanceInterval);
beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
}
serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
}
复制代码
先是创建 BeatInfo 对象,并填相关的属性信息,BeatInfo 是保存着实例心跳的相关信息,包括 ip 地址、端口号、所在集群、权重信息等
通过 beatReactor.addBeatInfo 创建心跳信息实现健康监测,参数有 ServiceName、groupName 和心跳实例对象,从而确定是哪个服务哪个组下面的实例,Naocs Server 必须确保注册的服务实例是健康的,而心跳检测就是服务健康检测的手段
serverProxy.registerService 实现服务的注册。
addBeatInfo 方法:
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);
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
}
复制代码
所谓心跳机制就是客户端通过 schedule 方法定时向服务端发送一个数据包,然后启动一个线程不断检测服务端的回应,如果在设定时间内没有收到服务端的回应,则认为服务器发生故障。Nacos 服务端根据客户端的心跳包不断更新服务状态。
registerService()方法
接下来就是 serverProxy.registerService 进行服务的注册,进入方法可以看到其实是一个 HTTP 协议的 POST 请求,也就是 Nacos 提供了 Open API 来实现服务的注册,SDK 进行了封装,这里不贴源码的内容了
总结
让我们总结一下,nacos 实现服务的注册是通过调用 NacosServiceRegistry 的 register()方法,方法中获取 serviceId 和 group 等信息,构建 BeatInfo 心跳实例对象,通过线程定时发送 BeatInfo 心跳信息,从而让服务端时刻知道服务的运行状态是否良好,真正注册的是 serverProxy.registerService()进行服务的注册,本质是发送 POST 请求给 nacos 服务端。下篇文章我们将分析 nacos 服务端对服务注册做了哪些操作。
评论