服务发现

服务发现就是查询实例列表。

客户端

客户端服务发现的入口在

com.alibaba.nacos.client.naming.NacosNamingService#getAllInstances(java.lang.String, java.lang.String, java.util.List, boolean)

--> com.alibaba.nacos.client.naming.core.HostReactor#getServiceInfo

getServiceInfo0

首先会通过getServiceInfo0方法,从缓存中获取数据。 serviceInfoMap就是本地的缓存。

private ServiceInfo getServiceInfo0(String serviceName, String clusters) {
    
    String key = ServiceInfo.getKey(serviceName, clusters);
    
    return serviceInfoMap.get(key);
}

updateService

首次进入可能是获取不到的,所以这里就会调用updateServiceNow方法进行更新服务列表。

com.alibaba.nacos.client.naming.core.HostReactor#updateServiceNow

--> com.alibaba.nacos.client.naming.core.HostReactor#updateService

先通过queryList去服务端获取实例列表

com.alibaba.nacos.client.naming.net.NamingProxy#queryList

reqApi(UtilAndComs.nacosUrlBase + "/instance/list", params, HttpMethod.GET);

如果获取的列表部位空,则调用processServiceJson进行解析。然后存入缓存。

serviceInfoMap.put(serviceInfo.getKey(), serviceInfo);

scheduleUpdateIfAbsent

在getServiceInfo的底部,有一个定时任务的方法,会定时从服务端拉取最新的服务列表,更新到缓存。

com.alibaba.nacos.client.naming.core.HostReactor#scheduleUpdateIfAbsent

addTask(new UpdateTask(serviceName, clusters));

在scheduleUpdateIfAbsent方法中,添加了一个UpdateTask的定时任务。定时任务的执行就是在run方法里。我们来下这个定时任务干了什么。

com.alibaba.nacos.client.naming.core.HostReactor.UpdateTask#run

这里的核心还是调用上面的updateService方法,从服务端获取最新的列表更新到缓存。 然后再finally中递归的调用定时任务,实现了轮询。

客户端的实现比较简单,我们在来看下服务端。

服务端

我们看到客户端调用的地址是/nacos/v1/ns/instance/list

reqApi(UtilAndComs.nacosUrlBase + "/instance/list", params, HttpMethod.GET);

对应服务端的接口在com.alibaba.nacos.naming.controllers.InstanceController#list

-->com.alibaba.nacos.naming.controllers.InstanceController#doSrvIpxt

先通过serviceManager.getService从缓存中拿到service,然后

-->service.srvIPs -->com.alibaba.nacos.naming.core.Service#srvIPs

-->allIPs

-->clusterObj.allIPs()

这里就是服务注册的时候注册的实例列表了。

OK,服务端的服务发现更简单,到此为止!

更多推荐