springCloud中如何通过服务名找到对应的ip
原文很详细,建议两篇一起看,以下内容整合出核心部分
spring-cloud-openfeign 源码解析
Spring Cloud Ribbon源码深度解析(没有源码阅读经验也能看懂)
面试官方答案:
在Spring Cloud Alibaba环境中,Feign调用时通过服务名到Nacos中寻址的过程可以分为以下几个步骤:
-
服务启动与注册: 当一个服务应用(包含Feign客户端)启动时,它会根据配置的spring.cloud.nacos.discovery.*属性自动向Nacos服务注册中心注册。这通常包括服务名(spring.application.name)、Nacos服务器地址(spring.cloud.nacos.discovery.server-addr)以及可能的命名空间ID和服务分组等信息。一旦注册成功,Nacos中就会记录该服务的实例信息,包括IP地址、端口号及健康状态等。
-
Feign客户端配置: 在使用Feign进行服务间调用前,需要在Feign客户端接口上添加相应的注解(如@FeignClient(“serviceName”)),其中”serviceName”即是要调用的服务名。这个服务名必须与目标服务在Nacos中注册的服务名匹配。
-
服务发现: 当Feign发起一次远程调用时,它依赖于Spring Cloud的负载均衡器(默认是Ribbon)。在初始化或每次请求时,Feign客户端会通过Spring Cloud的DiscoveryClient接口查询Nacos服务注册中心,以获取目标服务的所有可用实例列表。这个过程依据服务名进行查找,同时也考虑命名空间和服务分组的配置,确保找到的是正确的服务实例集合。
-
负载均衡与路由: 获取到服务实例列表后,负载均衡器(Ribbon)会根据内置的策略(如轮询、随机等)选择一个实例。选定实例后,Feign构建HTTP请求并直接与该实例通信。这个过程实现了服务路由,即根据服务名寻址到具体的实例地址并完成调用。
-
健康检查与重试: 在实际调用过程中,如果选定的实例不可用,Feign和Ribbon会根据配置的重试策略尝试其他实例,确保服务调用的健壮性。同时,Nacos也会持续监控服务实例的健康状态,及时剔除不健康的实例。
源码解析:
重点在第三步和第四步,以下是详细解读:
当ZoneAwareLoadBalancer在初始化时,会调用父类DynamicServerListLoadBalancer的构造方法,代码如下:
public DynamicServerListLoadBalancer(IClientConfig clientConfig, IRule rule, IPing ping, ServerList<T> serverList, ServerListFilter<T> filter, ServerListUpdater serverListUpdater) {
super(clientConfig, rule, ping);
this.isSecure = false;
this.useTunnel = false;
this.serverListUpdateInProgress = new AtomicBoolean(false);
this.updateAction = new NamelessClass_1();
this.serverListImpl = serverList;
this.filter = filter;
this.serverListUpdater = serverListUpdater;
if (filter instanceof AbstractServerListFilter) {
((AbstractServerListFilter)filter).setLoadBalancerStats(this.getLoadBalancerStats());
}
this.