2022年6月11日 作者 zeroheart

gateway 怎么轮训微服务实例的

1.如果自定义使用的微服务实例的?

参考:(26条消息) springcloud gateway 只访问本地或指定ip下的微服务项目_山巅的博客-CSDN博客_通过gateway访问微服务

1.1.LocalHostAwareRule extends PredicateBasedRule 继承PredicateBasedRule

@Slf4j
public class LocalHostAwareRule extends PredicateBasedRule {

    @Override
    public AbstractServerPredicate getPredicate() {
        return AbstractServerPredicate.alwaysTrue();
    }

    @Override
    public Server choose(Object key) {
        ILoadBalancer lb = getLoadBalancer();

        List<Server> allServers = lb.getAllServers();
        // 过滤服务列表
        List<Server> serverList = this.filterServers(allServers);

        Server server = getPredicate().chooseRoundRobinAfterFiltering(serverList, key).orNull();
        log.info(server != null ? server.toString() : "没有找到服务实例");
        return server;
    }

    private List<Server> filterServers(List<Server> serverList) {
        log.info(CollectionUtils.isEmpty(serverList) ? "没有找到服务实例列表" : serverList.toString());
        return Collections.unmodifiableList(serverList);
    }
}

1.2.增加配置RibbonRuleAutoConfiguration

@Configuration
@RequiredArgsConstructor
//一定要在ribbon默认的配置器之前加载
@AutoConfigureBefore(RibbonClientConfiguration.class)
//当ribbon.rule.enabled为false时不启用自定义过滤规则
@ConditionalOnProperty(value = "ribbon.rule.enabled", matchIfMissing = true)
public class RibbonRuleAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    //这里一定要配置为多例
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public PredicateBasedRule localHostAwareRule() {
        return new LocalHostAwareRule();
    }
}

2.AbstractServerPredicate 里面怎么找到微服务的

public abstract class AbstractServerPredicate implements Predicate<PredicateKey> {
 
    // 负载均衡器LoadBalancer规则:能从其获取到ILoadBalancer,从而得到一个对应的LoadBalancerStats实例
    protected IRule rule;
    // LoadBalancer状态信息。可以通过构造器指定/set方法指定,若没有指定的话将会从IRule里拿
    private volatile LoadBalancerStats lbStats;
    // 随机数。当过滤后还剩多台Server将从中随机获取
    private final Random random = new Random();
    // 下一个角标。用于轮询算法的指示
    private final AtomicInteger nextIndex = new AtomicInteger();
    // 一个特殊的Predicate:只有Server参数并无loadBalancerKey参数的PredicateKey,最终也是使用AbstractServerPredicate完成断言
    private final Predicate<Server> serverOnlyPredicate;
    
    public Predicate<Server> getServerOnlyPredicate() {
        return this.serverOnlyPredicate;
    }
}



AbstractServerPredicate,它的作用就是在众多Server的列表中,通过一定的过滤策略,T除不合格的Server,留下来合格的Server列表,进而供以选择

ZoneAffinityPredicate
Affinity:类同的,吸引力。它只会选取指定zone区域内的Server,言外之意就是会过滤掉其它区域的Server们。

ZoneAvoidancePredicate
Avoidance:避免、回避、躲开。它负责过滤掉这样的Server们:当某个zone非常糟糕,糟糕到统计达到了threshold阈值,那么就会过滤掉这个zone里面所有的Server们,所以该断言器是具有很强的zone区域意识的。


AvailabilityPredicate
availability:可用性,有效性。该断言器主要是对服务的可用性进行过滤(过滤掉不可用的服务器)。很明显,它的判断需要基于LoadBalancerStats/ServerStats来完成。


CompositePredicate
组合模式。它还具有“回退”到更多(不止一个)不同谓词之一的功能。如果主的Predicate产生的过滤服务器太少,它将一个接一个地尝试fallback的Predicate,直到过滤服务器的数量超过一定数量的阈值或百分比阈值。


参考:(26条消息) 【Ribbon路由规则器】服务筛选,过滤服务基础组件AbstractServerPredicate_唯空城的博客-CSDN博客

3.负载的策略

AbstractLoadBalancerRule

负载均衡策略的抽象类,在该类中定义了负载均衡器ILoadBalancer对象,该对象能够在具体实现选择服务策略时,获取到

一些负载均衡中维护的信息来作为分配依据,并以此设计一些算法来实现针对特定场景的高效策略


RandomRule
随机选择一个服务实例

RoundRobinRule
线性轮询的方式

RetryRule
实现了一个具备重试机制的实例选择功能


WeightedResponseTimeRule
该策略是对RoundRobinRule的扩展,增加了根据实例的运行情况来计算权重,并根据权重来挑选实例,以达到更优的分配效果

定时任务
serverWeightTimer.schedule(new DynamicServerWeightTask(), 0, serverWeightTaskTimerInterval);启动一个定时任务,用来为每个服务实例计算权重

该方法的实现主要分为两个步骤:
  根据LoadBalancerStats中记录的每个实例的统计信息,累加所有实例的平均响应时间,得到平均响应时间总和

totalResponseTime,该值会用于后续的计算。
   为负载均衡器中维护的实例清单逐个计算权重(从第一个开始),计算规则为weightSoFar+totalResponseTime

- 实例的平均响应时间,其中weightSoFar初始为零,并且每计算好一个权重需要累加到weightSoFar上供下一次计算使用



ClientConfigEnableRoundRobinRule
  该策略较为特殊,一般不直接使用它,因为本身没有特殊的处理逻辑,内部定义了一个RoundRobinRule,choose()方法默认使用RoundRobinRule的线性轮循机制,
通过继承该策略,在子类中做一些高级策略时通常有可能会存在一些无法实施的情况,那么就可以用父类的实现作为备选。


BestAvailableRule
ClientConfigEnableRoundRobinRule的子类,主要是找出并发请求数最小的一个

PredicateBasedRule
这是一个抽象策略,它也继承了ClientConfigEnabledRoundRobinRule

AbstractServerPredicate 然后就得到上文中的几种策略。


spring cloud ribbon 客户端负载均衡策略 – 简书 (jianshu.com)