客户端
- 会先从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)