OpenFeign远程调用负载均衡原理详解

本文深入探讨了SpringCloud Alibaba中FeignClient的负载均衡机制,解析了其默认的轮询策略实现,并提供了自定义负载均衡策略的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      SpringCloudAlibaba中使用OpenFeign时,默认的负载均衡策略是轮询调用。我们不做任何配置的时候,使用OpenFeign调用的时候,框架中是如何把负载均衡LoadBalanced和FeignClient结合到一起的?我们一起来分析一下。

1 DefaultFeignLoadBalancedConfiguration

位置:org.springframework.cloud.openfeign.ribbon.DefaultFeignLoadBalancedConfiguration

图1.1

项目启动的时候,会用LoadBalancerFeignClient注册一个feign.Client到ioc容器中。

FeignClientFactoryBean会生成一个@FeignClient注解的对应的service实例。

2 FeignClientFactoryBean

位置:org.springframework.cloud.openfeign.FeignClientFactoryBean

图2.1
图2.2

FeignClientFactoryBean实现了FactoryBean,我们都知道,在spring中实现了FactoryBean的类在spring生命周期过程中,spring会把 getObject() 返回的实例注册到ioc容器。方便以后实例的调用。

在spring生命周期过程中会调用getObject(),从ioc容器中获取到的client就是第一步注册到ioc容器的负载均衡实例LoadBalancerFeignClient,通过builder.client(client)到Feign.builder中。如图2.2。

图2.3
图2.4

现在我们可以分析图2.2最后一行。return targeter.target(this, builder, context, target)。以下图2.5和图2.6为FeignClientFactoryBean的getObject最终要初始化的实例。可以明显的看到创建了一个关于SynchronousMethodHandler.Factory的实例。第一个client参数就是上面已经注册好的LoadBalancerFeignClient的实例。

图2.5
图2.6

SynchronousMethodHandler 是个拦截器。项目初始话过程中,会为所有加了@FeignClient的service接口结合FeignClientFactoryBean生成对应接口的代理对象,客户端调用接口时会调用SynchronousMethodHandler的invoke方法。

图2.7
图2.8

 从图2.9可以看出调用servcie接口时是通过 client.execute(request, options) 调用的。client即为上面已经注册好的LoadBalancerFeignClient的实例。

图2.9

 3 探究client调用时如何做负载的?默认调用的哪种策略的负载?

跟进executeWithLoadBalancer方法。

图3.1

跟进submit方法

图3.2

可以看到图3.3中server为null的时候,执行selectServer()方法。跟进selectServer()。

图3.3

跟进getServerFromLoadBalancer()。

图3.4

继续跟进,可以看到 ILoadBalancer lb = getLoadBalancer(),可以获取到要负载的对应接口的服务列表。ILoadBalancer主要就是一个负载均衡器的接口,作用就是从被负载的服务列表里选出一个服务去调用。

下图为ILoadBalancer的实现类。默认调用的是ZoneAwareLoadBalancer。

图3.5

图3.5可以看出,Server svc = lb.chooseServer(loadBalancerKey),是从服务列表里面选择一个服务去调用。

跟进chooseServer()方法。默认会按照图3.6执行。

图3.6

继续跟进super.chooseServer(key)方法。红框中的rule有多种实现。图3.7调用的时候默认调用的是RoundRobinRule。即轮询策略。至此,我们已探究出FeignClient默认情况下会有负载均衡,且用的是netflix的ribbon的轮询策略。

图3.7
图3.8

结合图3.7从3.8中可以看出rule默认的就是 RoundRobinRule()。

4 我们如何自定义配置来修改默认的负载均衡策略呢?

位置:org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration。

加载 ribbonLoadBalancer 方法时会从ioc容器中查找注册好的Rule来通过参数注入到ZoneAwareLoadBalancer实例中。如果使用默认的,此时的rule默认使用的是ZoneAvoidanceRule,即依赖的rule为RoundRobinRule roundRobinRule = new RoundRobinRule()。

所以如果想定义一个需要的rule,只需要添加以下配置就可以了。

@Configuration
public class TestConfiguration {
    @Bean
    public IRule ribbonRule() {
        return new RandomRule();  //规则可以自己定义,也可以选择已有的
    }

}

 上述配置代码添加后会注册到ioc容器,下图代码为初始化 ILoadBalancer 实例时通过参数注入的方式 把ioc容器中注入好的rule实例传递给这个方法,完成负载策略的实现。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荆茗Scaler

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值