天天看點

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)

           

繼續閱讀