【springcloud】LoadBalancerClient选择应用实例的源码分析

继上一篇【springcloud】RestTemplate的三种使用方式,现在分析下LoadBalancerClient是如何获取服务实例的

源码分析

通过第二种方式来查看源码


@RestController
public class ClientController {
    @Autowired
    private LoadBalancerClient loadBalancerClient;
 
    @GetMapping("getMsg")
    public String getMsg() {
       
        RestTemplate template = new RestTemplate();
        ServiceInstance instance = loadBalancerClient.choose("PRODUCT");
        String url = String.format("http://%s:%s", instance.getHost(), instance.getPort() + "/msg");
        return template.getForObject(url, String.class);
    }

进入loadBalanceClient的choose方法,其实现类为RibbonLoadBalancerClient源码如下

public ServiceInstance choose(String serviceId) {
        Server server = this.getServer(serviceId);
        return server == null ? null : new RibbonLoadBalancerClient.RibbonServer(
                        serviceId, server, 
                        this.isSecure(server, serviceId), 
                        this.serverIntrospector(serviceId).getMetadata(server));
    }

可以发现,服务是通过该类的getServer(String serviceId)获得

    protected Server getServer(String serviceId) {
        return this.getServer(this.getLoadBalancer(serviceId));
    }

进入getServer(ILoadBalancer loadBalancer)

    protected Server getServer(ILoadBalancer loadBalancer) {
        return loadBalancer == null ? null : loadBalancer.chooseServer("default");
    }

这里调用ILoadBalancer的chooseServer(Object var1)方法来获得实例,进入其实现类BaseLoadBalancer查看该方法

public Server chooseServer(Object key) {
        if (this.counter == null) {
            this.counter = this.createCounter();
        }

        this.counter.increment();
        if (this.rule == null) {
            return null;
        } else {
            try {
                return this.rule.choose(key);
            } catch (Exception var3) {
                logger.warn("LoadBalancer [{}]:  Error choosing server for key {}",
                     new Object[]{this.name, key, var3});
                return null;
            }
        }
    }

核心代码为this.rule.choose(key),rule为负载均衡的机制,默认为轮询,在该类中我们可以看到

private static final IRule DEFAULT_RULE = new RoundRobinRule();
public BaseLoadBalancer() {
        this.rule = DEFAULT_RULE;
        //省略其他属性
    }

所以最终是根据一种机制,来从所有的服务中获取一个实例来返回

更改负载均衡的策略

策略列表:

策略名策略声明策略描述实现说明
BestAvailableRulepublic class BestAvailableRule extends ClientConfigEnabledRoundRobinRule选择一个最小的并发请求的server逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRulepublic class AvailabilityFilteringRule extends PredicateBasedRule过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRulepublic class WeightedResponseTimeRule extends RoundRobinRule根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成status时,使用roubine策略选择server。
RetryRulepublic class RetryRule extends AbstractLoadBalancerRule对选定的负载均衡策略机上重试机制。在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRulepublic class RoundRobinRule extends AbstractLoadBalancerRuleroundRobin方式轮询选择server轮询index,选择index对应位置的server
RandomRulepublic class RandomRule extends AbstractLoadBalancerRule随机选择一个server在index上随机,选择index对应位置的server
ZoneAvoidanceRulepublic class ZoneAvoidanceRule extends PredicateBasedRule复合判断server所在区域的性能和server的可用性选择server使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

更改方式:在yml中进行配置

PRODUCT:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ClientConfigEnabledRoundRobinRule

PRODUCT为你需要配置的应用名称

 

 


参考:

Ribbon负载均衡策略配置

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值