当咱们在我的项目中调用本人实现的Feignclient负载平衡中如何起作用?请看下图:


图一

在图一中咱们能够发现,在ConsumerController中调用自定义的DemoFeignClient办法时,通过spring容器中对DemoFeignclient的代理类的调用最终通过feign.SynchronousMethodHandler.invoke()->openfeign.loadbalancer.execute()->org.springframework.cloud.loadbalancer.blocking.client.FeignBlockingLoadBalancerClient.choose()->org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer.choose()这样的调用链,最终执行spring cloud loadbalaner中的轮询负载均横策略!

然而,上图中的这些要害类是如何组合起来发挥作用呢?请咱们一起持续剖析!spring cloud我的项目启动后,spring容器解析并加载LoadBalancerClientConfiguration.java配置文件(如下图所示)

图二

而后将"reactorServiceInstanceLoadBalancer"注册到beanDefinitionMap中。
而后会扫描咱们申明的controller,因为conroller中注入了DemoFeignClient,因而spring容器会递归创立DemoFeignClient,创立DemoFiegnClient过程中会通过AbstractAutowireCapableBeanFactory.obtainFromSupplier()注入instanceSupplier实例,也就是FeignClientFactoryBean实例!

上面是org.springframework.cloud.openfeign.FeignClientsRegistrar.registerFeignClient()办法次要逻辑:

private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata,            Map<String, Object> attributes) {          //疏忽非核心代码片段            BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(clazz, () -> {            //设置url            factoryBean.setUrl(getUrl(beanFactory, attributes));            //设置门路            factoryBean.setPath(getPath(beanFactory, attributes));            //decode404 布尔值            factoryBean.setDecode404(Boolean.parseBoolean(String.valueOf(attributes.get("decode404"))));            Object fallback = attributes.get("fallback");            //设置fallback            if (fallback != null) {                factoryBean.setFallback(fallback instanceof Class ? (Class<?>) fallback                        : ClassUtils.resolveClassName(fallback.toString(), null));            }            //设置fallback工厂类            Object fallbackFactory = attributes.get("fallbackFactory");            if (fallbackFactory != null) {                factoryBean.setFallbackFactory(fallbackFactory instanceof Class ? (Class<?>) fallbackFactory                        : ClassUtils.resolveClassName(fallbackFactory.toString(), null));            }            //实例化咱们申明的DemoClient            return factoryBean.getObject();        });}

这还没有完,org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject()中最终执行loadBalance();在loadBalance()中实例化FeignInvocationHandler;

在我的项目启动胜利之后,咱们调用DemoFeignClient中的办法时

图三

通过图三能够发现,形容DemoFeignClient的RootBeanDefinition的类中还有一个叫“instanceSupplier”的类型属性,它的值是“FeignClientsRegistrar$lambda”,那么这个类时什么时候被注入进来的呢?答案就是下面剖析我的项目启动过程中spring容器依据RootBeanDefinition对DemoFeignClient的形容,通过对"FeignClientsRegistrar$lambda"的调用实现对DemoFeignClient实例的创立。

在实现创立DemoFeignClient实例后,咱们调用org.springframework.cloud.openfeign.loadbalancer。FeignBlockingLoadBalancerClient.execute()执行负载平衡策略时,执行到如下代码块

Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator                .getSupportedLifecycleProcessors(                        loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),                        RequestDataContext.class, ResponseData.class, ServiceInstance.class);

"loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class)"逻辑会获取LoadBalancer实例,最终调用LoadBalancerClientConfiguration.java中的reactorServiceInstanceLoadBalancer()实现创立负载平衡实例逻辑

@Bean    @ConditionalOnMissingBean    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,            LoadBalancerClientFactory loadBalancerClientFactory) {        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);        //创立负载平衡实例,而且咱们发现默认的负载平衡实例是轮询负载平衡实例        return new RoundRobinLoadBalancer(                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);    }

ok,截止到目前为止,咱们的负载平衡实例曾经创立实现!

这样一来,咱们通过openfeign进行近程调用时,通过下图的调用链

图四

FeignInvocationHandler.invoke()->SynchronousMethodHandler.invoke()->org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient.execute()->org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.choose()->org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer.choose(),这样的调用链最终依据RoundRobinLoadBalancer.choose()获取服务实例。

public Mono<Response<ServiceInstance>> choose(Request request) {        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider                .getIfAvailable(NoopServiceInstanceListSupplier::new);        //返回服务实例        return supplier.get(request).next()                .map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));    }

拿到服务实例后,FeignBlockingLoadBalancerClient.execute()中最终通过LoadBalancerUtils.executeWithLoadBalancerLifecycleProcessing()获取响应后果!
上面是具体代码逻辑:

static Response executeWithLoadBalancerLifecycleProcessing(Client feignClient, Request.Options options,            Request feignRequest, org.springframework.cloud.client.loadbalancer.Request lbRequest,            org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse,            Set<LoadBalancerLifecycle> supportedLifecycleProcessors, boolean loadBalanced, boolean useRawStatusCodes)            throws IOException {        supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse));        try {            //通过openfeign调用,获取响应后果            Response response = feignClient.execute(feignRequest, options);            if (loadBalanced) {                supportedLifecycleProcessors.forEach(                        lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS,                                lbRequest, lbResponse, buildResponseData(response, useRawStatusCodes))));            }            return response;        }        catch (Exception exception) {            if (loadBalanced) {                supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(                        new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbRequest, lbResponse)));            }            throw exception;        }    }