了解nacos的心跳机制,需要先了解nacos的服务注册原理;可先阅读https://blog.csdn.net/LiaoHongHB/article/details/103993074
当nacos进行服务注册的时候,NacosServiceRegistry.class会调用register()方法进行服务注册,该方法中调用了namingService.registerInstance()方法进行服务注册的逻辑。
@Override
public void register(Registration registration) {
if (StringUtils.isEmpty(registration.getServiceId())) {
log.warn("No service to register for nacos client...");
return;
}
String serviceId = registration.getServiceId();
Instance instance = new Instance();
instance.setIp(registration.getHost());
instance.setPort(registration.getPort());
instance.setWeight(nacosDiscoveryProperties.getWeight());
instance.setClusterName(nacosDiscoveryProperties.getClusterName());
instance.setMetadata(registration.getMetadata());
try {
namingService.registerInstance(serviceId, instance);
log.info("nacos registry, {} {}:{} register finished", serviceId,
instance.getIp(), instance.getPort());
}
catch (Exception e) {
log.error("nacos registry, {} register failed...{},", serviceId,
registration.toString(), e);
}
}
NacosNamingService实现了NamingService的接口;然后在namingService.registerInstance()方法中,会做两件事情,第一件事就是组装心跳包BeatInfo,并且发送心跳:
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);
this.beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
}
this.serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
}
NacosNamingService中的构造函数,会调用init()方法,然后在init方法中会执行一个BeatReactor线程
NacosNamingService中的构造函数和init()方法:
public NacosNamingService(Properties properties) {
this.init(properties);
}
private void init(Properties properties) {
this.serverList = properties.getProperty("serverAddr");
this.initNamespace(properties);
this.initEndpoint(properties);
this.initWebRootContext();
this.initCacheDir();
this.initLogName(properties);
this.eventDispatcher = new EventDispatcher();
this.serverProxy = new NamingProxy(this.namespace, this.endpoint, this.serverList);
this.serverProxy.setProperties(properties);
//执行心跳的线程
this.beatReactor = new BeatReactor(this.serverProxy, this.initClientBeatThreadCount(properties));
this.hostReactor = new HostReactor(this.eventDispatcher, this.serverProxy, this.cacheDir, this.isLoadCacheAtStart(properties), this.initPollingThreadCount(properties));
}
BeatReactor的构造函数中创建了一个ScheduledExecutorService线程操作对象,然后执行的方法是BeatReactor.BeatProcessor();在BeatProcessor()方法中又执行了一个线程操作,BeatTask线程,然后在BeatTask线程中调用了sendBeat()方法,将心跳包作为参数;
BeatReactor的构造函数:创建一个线程执行类,并执行BeatProcessor()方法
public BeatReactor(NamingProx