用戶端
- 會先從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)