Gateway有两种客户端负载均衡器,LoadBalancerClientFilter和ReactiveLoadBalancerClientFilter。
LoadBalancerClientFilter使用一个Ribbon的阻塞式LoadBalancerClient,Gateway建议使用ReactiveLoadBalancerClientFilter,
可以通过设置spring.cloud.loadbalancer.ribbon.enabled=false,切换到
ReactiveLoadBalancerClientFilter
无论使用Ribbon还是LoadBalancer,在Route中配置的lb是一样的,如下:
serviceId为providerService
#=======================路由配置RouteDefinition=======================
#id:路由标识,具有唯一性
spring.cloud.gateway.routes[0].id=provider-http
#url:目标服务地址,请求转发后的地址,lb:协议表示开启负载均衡
#uri: lb://renren-api
spring.cloud.gateway.routes[0].uri=lb://providerService
#predicates:断言/路由条件,匹配 HTTP请求内容
#转发地址格式: uri/nacos/provider/**
spring.cloud.gateway.routes[0].predicates[0]=Path=/provider-http/**
两种负载均衡都引入了LoadBalancerProperties健康检查类
@ConfigurationProperties("spring.cloud.loadbalancer")
public class LoadBalancerProperties {
private LoadBalancerProperties.HealthCheck healthCheck = new LoadBalancerProperties.HealthCheck();
...省略...
public static class HealthCheck {
private int initialDelay = 0;
private Duration interval = Duration.ofSeconds(25L);
private Map path = new LinkedCaseInsensitiveMap();
...省略...
}
}
gateway中的自动配置类GatewayLoadBalancerClientAutoConfiguration
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({LoadBalancerClient.class, RibbonAutoConfiguration.class, DispatcherHandler.class})
@AutoConfigureAfter({RibbonAutoConfiguration.class})
@EnableConfigurationProperties({LoadBalancerProperties.class})
public class GatewayLoadBalancerClientAutoConfiguration {
public GatewayLoadBalancerClientAutoConfiguration() {
}
@Bean
@ConditionalOnBean({LoadBalancerClient.class})
//缺失LoadBalancerClientFilter和ReactiveLoadBalancerClientFilter的条件下,就new LoadBalancerClientFilter
//也就是说,默认情况下是使用LoadBalancerClientFilter的
@ConditionalOnMissingBean({LoadBalancerClientFilter.class, ReactiveLoadBalancerClientFilter.class})
@ConditionalOnEnabledGlobalFilter
public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client, LoadBalancerProperties properties) {
return new LoadBalancerClientFilter(client, properties);
}
}
该自动配置类需要在RibbonAutoConfiguration自动配置类之后执行,该类是spring-cloud-netflix-ribbon的自动配置类,因此需要引入下面的jar包依赖
引入依赖
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
使用默认的ribbon,则ribbon的配置如下
#=======================ribbon配置(使用netflix的Ribbon负载均衡)=======================
#关闭nacos集成ribbon,否则ribbon客户端会从nacos注册中心获取服务列表
ribbon.nacos.enabled=false
#配置serviceId为providerService的服务List
providerService.ribbon.listOfServers=http://192.168.10.1:8080,http://192.168.10.2:8080
#配置serviceId为providerService的服务负载均衡
#providerService.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
providerService.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.AvailabilityFilteringRule
其他的ribbon的配置项如下
.ribbon.NFLoadBalancerClassName: ILoadBalancer
.ribbon.NFLoadBalancerRuleClassName: IRule
.ribbon.NFLoadBalancerPingClassName: IPing
.ribbon.NIWSServerListClassName: ServerList
.ribbon.NIWSServerListFilterClassName: ServerListFilter
Spring Cloud Load Balancer
并不是一个独立的项目,而是spring-cloud-commons
其中的一个模块,因此很多配置和类可以在spring-cloud-common中找到。
官网文档地址
gateway中的自动配置类GatewayReactiveLoadBalancerClientAutoConfiguration
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({LoadBalancerClient.class, ReactiveLoadBalancer.class, LoadBalancerAutoConfiguration.class, DispatcherHandler.class})
@AutoConfigureBefore({GatewayLoadBalancerClientAutoConfiguration.class})
@AutoConfigureAfter({LoadBalancerAutoConfiguration.class})
@EnableConfigurationProperties({LoadBalancerProperties.class})
public class GatewayReactiveLoadBalancerClientAutoConfiguration {
public GatewayReactiveLoadBalancerClientAutoConfiguration() {
}
@Bean
@ConditionalOnBean({LoadBalancerClientFactory.class})
@ConditionalOnMissingBean({ReactiveLoadBalancerClientFilter.class})
//这个条件很重要
@Conditional({GatewayReactiveLoadBalancerClientAutoConfiguration.OnNoRibbonDefaultCondition.class})
@ConditionalOnEnabledGlobalFilter
public ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory, LoadBalancerProperties properties) {
return new ReactiveLoadBalancerClientFilter(clientFactory, properties);
}
private static final class OnNoRibbonDefaultCondition extends AnyNestedCondition {
private OnNoRibbonDefaultCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnMissingClass({"org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient"})
static class RibbonLoadBalancerNotPresent {
RibbonLoadBalancerNotPresent() {
}
}
//spring.cloud.loadbalancer.ribbon.enabled=false,才会使用ReactiveLoadBalancerClientFilter
@ConditionalOnProperty(
value = {"spring.cloud.loadbalancer.ribbon.enabled"},
havingValue = "false"
)
static class RibbonNotEnabled {
RibbonNotEnabled() {
}
}
}
}
引入依赖
org.springframework.cloud
spring-cloud-starter-loadbalancer
配置如下(从配置文件中读取服务,而不是从服务注册中心自动发现服务)
注意:如果在项目的类路径下存在Spring Cloud Ribbon相关的类,需要通过配置关闭Ribbon功能,因为Spring Cloud默认优先使用Ribbon,因此spring.cloud.loadbalancer.ribbon.enabled禁用调Ribbon,这也是上面刚提到过的
#=======================SpringCloudLoadBalancer配置服务列表=======================
#使用ReactiveLoadBalancerClient时通过该参数禁用调ribbon
spring.cloud.loadbalancer.ribbon.enabled=false
#配置providerService的instances,不是从注册中心自动发现服务实例
spring.cloud.discovery.client.simple.instances.providerService[0].uri=http://192.168.10.1:8080
spring.cloud.discovery.client.simple.instances.providerService[1].uri=http://192.168.10.2:8080
#指定健康检查请求路径,默认健康检查路径是/actuator/health
spring.cloud.loadbalancer.health-check.path.providerService=/custom/customHealthCheckPath
#运行状况检查计划程序的初始延迟值
spring.cloud.loadbalancer.health-check.initial-delay=0
#重新运行运行状况检查计划程序的时间间隔
spring.cloud.loadbalancer.health-check.interval=5s
#启用预定义的负载平衡器配置
spring.cloud.loadbalancer.configurations=health-check
SimpleDiscoveryClient
网关参考文档simplediscoveryclient
如果在类路径中没有支持从注册中心发现服务的DiscoveryClient实例,则将使用SimpleDiscoveryClient实例,该实例使用SimpleDiscoveryProperties来获取有关服务和实例的信息。参考上面的配置文件中的配置
public class SimpleDiscoveryClient implements DiscoveryClient {
private SimpleDiscoveryProperties simpleDiscoveryProperties;
public SimpleDiscoveryClient(SimpleDiscoveryProperties simpleDiscoveryProperties) {
this.simpleDiscoveryProperties = simpleDiscoveryProperties;
}
public String description() {
return "Simple Discovery Client";
}
public List getInstances(String serviceId) {
List serviceInstances = new ArrayList();
List serviceInstanceForService = (List)this.simpleDiscoveryProperties.getInstances().get(serviceId);
if (serviceInstanceForService != null) {
serviceInstances.addAll(serviceInstanceForService);
}
return serviceInstances;
}
public List getServices() {
return new ArrayList(this.simpleDiscoveryProperties.getInstances().keySet());
}
public int getOrder() {
return this.simpleDiscoveryProperties.getOrder();
}
}
SimpleDiscoveryProperties 服务实例的属性配置
@ConfigurationProperties(
prefix = "spring.cloud.discovery.client.simple"
)
public class SimpleDiscoveryProperties {
//在配置文件中配置的实例属性
private Map> instances = new HashMap();
private DefaultServiceInstance local = new DefaultServiceInstance((String)null, (String)null, (String)null, 0, false);
private int order = 0;
}
DefaultServiceInstance默认的服务实例定义
public class DefaultServiceInstance implements ServiceInstance {
private String instanceId;
private String serviceId;
private String host;
private int port;
private boolean secure;
private Map metadata;
private URI uri;
...省略...
}
参考https://blog.csdn.net/abu935009066/article/details/112296435