2022年6月11日
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 然后就得到上文中的几种策略。