admin管理员组文章数量:1794759
springCloud面试之Feign
什么是Feign
Feign是Netflix公司开发的声明式、模板化的的HTTP客户端工具,可以帮助我们更加优雅的调用HTTP API,同时也使得微服务之间的调用变得简单。 springCloud feign进行了增强,使得Feign更够支持SpringMvc注解
Feign的作用先来看一下feign流程
在微服务启动时,Feign会进行包扫描,对加@FeignClient注解的接口,按照注解的规则,创建远程接口的本地JDK Proxy代理实例。然后,将这些本地Proxy代理实例,注入到Spring IOC容器中。当远程接口的方法被调用,由Proxy代理实例去完成真正的远程访问,并且返回结果。
下面跟着代码我们来一起看一下:
1.这里重点讲一下LoadBalancerFeignClient
public Response execute(Request request, Options options) throws IOException { try { //获取本次请求的URI URI asUri = URI.create(request.url()); //获取服务的名称,FeignClient中定义的服务的名称 String clientName = asUri.getHost(); URI uriWithoutHost = cleanUrl(request.url(), clientName); //存储URI RibbonRequest ribbonRequest = new RibbonRequest(this.delegate, request, uriWithoutHost); //存储connectTimeout、readTimeout的时间等 IClientConfig requestConfig = this.getClientConfig(options, clientName); /*接下来的处理,会分成两步 *1、this.lbClient(clientName) //这里主要是通过CachingSpringLoadBalancerFactory获取FeignLoadBalancer * 下面2步骤会分析如何获取的 *2、executeWithLoadBalancer(ribbonRequest, requestConfig)//这里就是通过LoadBalancer先选出需要调用的server,然后发送请求; * 具体是先通过LoadBalancerCommand获取到要调用的server信 * 然后再通过httpclient发送请求; * 从LazyTracingFeignClient * 下面3步骤会分析如何获取的 * */ return ((RibbonResponse)this.lbClient(clientName).executeWithLoadBalancer(ribbonRequest, requestConfig)).toResponse(); } catch (ClientException var8) { IOException io = this.findIOException(var8); if (io != null) { throw io; } else { throw new RuntimeException(var8); } } } }2.CachingSpringLoadBalancerFactory#create(String clientName)
public FeignLoadBalancer create(String clientName) { //private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap(); //cache是一个volatile修饰的Map, FeignLoadBalancer client = (FeignLoadBalancer)this.cache.get(clientName); if (client != null) { return client; } else { //缓存中没有找到,这里先进行config初始化; IClientConfig config = this.factory.getClientConfig(clientName); //从SpringClientFactory中获取ZoneAwareLoadBalancer //ZoneAwareLoadBalancer是ribbon中一个非常重要的类,它用来获取eureka中的server列表,并且进行服务列表的更新; ILoadBalancer lb = this.factory.getLoadBalancer(clientName); ServerIntrospector serverIntrospector = (ServerIntrospector)this.factory.getInstance(clientName, ServerIntrospector.class); //创建FeignLoadBalancer实例 FeignLoadBalancer client = this.loadBalancedRetryFactory != null ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector, this.loadBalancedRetryFactory) : new FeignLoadBalancer(lb, config, serverIntrospector); //将该FeignLoadBalancer放入容器中 this.cache.put(clientName, client); return (FeignLoadBalancer)client; }3.选取server、并进行调用
- AbstractLoadBalancerAwareClient#executeWithLoadBalancer()
- LoadBalancerCommand.submit()先通过ZoneAwareLoadBalancer获取到server信,再执行调用
4.FeignLoadBalancer#FeignLoadBalancer.RibbonResponse execute(…)
public FeignLoadBalancer.RibbonResponse execute(FeignLoadBalancer.RibbonRequest request, IClientConfig configOverride) throws IOException { Options options; if (configOverride != null) { //这里会覆盖RibbonProperties中的信 RibbonProperties override = RibbonProperties.from(configOverride); options = new Options(override.connectTimeout(this.connectTimeout), override.readTimeout(this.readTimeout)); } else { options = new Options(this.connectTimeout, this.readTimeout); } /*下面会通过client进行查询,由于我的项目中引入了zipkin,所以这里会调用org.springframework.cloud.sleuth.instrument.web.client.feign.LazyTracingFeignClient * ==>LazyTracingFeignClient.execute(Request request, Options options) * ==>TracingFeignClient.execute(Request request, Options options) * ==>Client.Default.execute(Request request, Options options) */ Response response = request.client().execute(request.toRequest(), options); return new FeignLoadBalancer.RibbonResponse(request.getUri(), response); } 推荐阅读:springCloud面试之feign+ribbon+hystirx交互概览
本文标签: SpringCloudFeign
版权声明:本文标题:springCloud面试之Feign 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686857987a111053.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论