天天看点

nacos服务发现源码分析客户端服务端

客户端

  • 会先从serviceInfoMap缓存中获取服务实例,如果缓存没有才访问接口。执行一个定时10s的更新任务更新缓存。
  • 传udp端口号,相当于订阅了该服务。比如客户端1订阅服务2,当服务2中实例上线或下线时,会发送udp给服务1
NacosNamingService.getAllInstances(String serviceName, String groupName, List<String> clusters, boolean subscribe)
    hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
        updateServiceNow(serviceName, clusters);
            NamingProxy.queryList(String serviceName, String clusters, int udpPort, boolean healthyOnly)
                //get /nacos/v1/ns/instance/list
                reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/list", params, HttpMethod.GET);
        scheduleUpdateIfAbsent(String serviceName, String clusters)
            addTask(new UpdateTask(serviceName, clusters));
                executor.schedule(task, DEFAULT_DELAY, TimeUnit.MILLISECONDS)
           

服务订阅

PushReceiver.run()
    udpSocket.receive(packet)
    ack = "{\"type\": \"push-ack\""
                        + ", \"lastRefTime\":\"" + pushPacket.lastRefTime
                        + "\", \"data\":" + "\"\"}";
    //确认ack
    udpSocket.send(new DatagramPacket(ack.getBytes(Charset.forName("UTF-8")),
                    ack.getBytes(Charset.forName("UTF-8")).length, packet.getSocketAddress()));

           

EnableDiscoveryClient注解原理

这个注解通过@Import引入了一个Selector,当autoRegister属性为true是,这个Selector会向容器注入org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration,这是一个空的Configuration,其它服务注册的实现可以通过@AutoConfigureAfter来条件注入自己的服务注册自动配置类。

比如Nacos的服务注册:

@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
		AutoServiceRegistrationAutoConfiguration.class })
public class NacosDiscoveryAutoConfiguration {
           

服务端

除了查询服务列表,还会将客户端传来的ip udp端口号加进clientMap,clientMap key是service name,value相当于是订阅 了该服务的客户端列表(ip+端口号)

InstanceController.list(HttpServletRequest request)
    int udpPort = Integer.parseInt(WebUtils.optional(request, "udpPort", "0"));
    doSrvIpxt(namespaceId, serviceName, agent, clusters, clientIP, udpPort, env, isCheck, app, tenant, healthyOnly);
        pushService.addClient(namespaceId, serviceName, clusters, agent, new InetSocketAddress(clientIP, udpPort), pushDataSource, tid, app)
            addClient(client)

           

继续阅读