前言:
我们知道 Spring Cloud Gateway 是一个高性能网关,具备负载均衡的能力,那你知道 Gateway 的负载均衡是怎么实现的吗?本篇我们来分析一下 Spring Cloud Gateway 的负载均衡的实现。
Spring Cloud Gateway 的负载均衡实现
我们在阅读源码的时候常常会去看 META-INF 下的 spring.factories,我们去该文件下看看能不能找到一点更负责均衡相关的代码,spring.factories 文件内容如下:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayResilience4JCircuitBreakerAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayNoLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration,\
org.springframework.cloud.gateway.discovery.GatewayDiscoveryClientAutoConfiguration,\
org.springframework.cloud.gateway.config.SimpleUrlHandlerMappingGlobalCorsAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayReactiveLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.gateway.config.GatewayReactiveOAuth2AutoConfiguration
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.gateway.config.GatewayEnvironmentPostProcessor
在 spring.factories 文件中我们看到了 GatewayNoLoadBalancerClientAutoConfiguration 和 GatewayReactiveLoadBalancerClientAutoConfiguration 这两个配置类,这两个配置类中都有 LoadBalancer 关键字,大胆猜测这两个配置类和 Gateway 的负载均衡有关系。
GatewayNoLoadBalancerClientAutoConfiguration 源码解析
GatewayNoLoadBalancerClientAutoConfiguration 直译是网关无负载均衡器客户端自动配置类,该类的实际作用是当 Gateway 转发的目标 url 中配置的是lb 约束时抛出NotFoundException异常。
//网关无负载均衡器客户端自动配置类
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnMissingClass({
"org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer"})
@ConditionalOnMissingBean({
ReactiveLoadBalancer.class})
@EnableConfigurationProperties({
GatewayLoadBalancerProperties.class})
@AutoConfigureAfter({
GatewayReactiveLoadBalancerClientAutoConfiguration.class})
public class GatewayNoLoadBalancerClientAutoConfiguration {
public GatewayNoLoadBalancerClientAutoConfiguration() {
}
//初始化 NoLoadBalancerClientFilter bean
@Bean
@ConditionalOnMissingBean({
ReactiveLoadBalancerClientFilter.class})
public GatewayNoLoadBalancerClientAutoConfiguration.NoLoadBalancerClientFilter noLoadBalancerClientFilter(GatewayLoadBalancerProperties properties) {
return new GatewayNoLoadBalancerClientAutoConfiguration.NoLoadBalancerClientFilter(properties.isUse404());
}
//内部类 NoLoadBalancerClientFilter
protected static class NoLoadBalancerClientFilter implements GlobalFilter, Ordered {
private final boolean use404;
public NoLoadBalancerClientFilter(boolean use404) {
this.use404 = use404;