💨 作者:
laker
,因为喜欢LOL滴神faker
,又是NBA湖人队🏀(laker
)粉丝儿(主要是老詹的粉丝儿),本人又姓李,故取笔名:laker
❤️喜欢分享自己工作中遇到的问题和解决方案,以及一些读书笔记和心得分享。
🌰本人创建了微信公众号【Java大厂面试官】,用于和大家交流分享
🏰 个人微信【lakernote】,加作者备注下暗号:cv之道
。
文章目录
本文Spring Cloud Gateway 版本:2020.0.0
Spring Boot版本:2.4.1
前言
拿着最新版本来实战一波负载均衡,毕竟之前都是demo级别的玩具车
,但是遇到坑了,
官网说用lb://lakerservice
形式即可,但是配置完成后,并未生效。
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
这个官网没有详细说明,查资料也没有,排查结果如下:
必须加入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
Spring Cloud Ribbon 高版本移除了
看到这儿,我靠,大呼
ribbon凉了啊
原理参考类:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ ReactiveLoadBalancer.class, LoadBalancerAutoConfiguration.class, DispatcherHandler.class })
@AutoConfigureAfter(LoadBalancerAutoConfiguration.class)
@EnableConfigurationProperties(GatewayLoadBalancerProperties.class)
public class GatewayReactiveLoadBalancerClientAutoConfiguration {
@Bean
@ConditionalOnBean(LoadBalancerClientFactory.class)
@ConditionalOnMissingBean(ReactiveLoadBalancerClientFilter.class)
@ConditionalOnEnabledGlobalFilter
public ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory,
GatewayLoadBalancerProperties properties, LoadBalancerProperties loadBalancerProperties) {
return new ReactiveLoadBalancerClientFilter(clientFactory, properties, loadBalancerProperties);
}
}
#websocket负载均衡
- id: websocket_route
# lb代表服务名,
# 这里负载所有的websocket
uri: lb:ws://xx-ws
predicates:
- Path=/websocket/**
Spring Cloud Loadbalancer
Spring Cloud提供了自己的客户端负载均衡器抽象和实现。对于负载平衡机制,ReactiveLoadBalancer
已添加了接口,并为其提供了基于Round-Robin和Random的实现。为了获得实例以从反应式中进行选择ServiceInstanceListSupplier
。当前,我们支持基于服务发现的实现,ServiceInstanceListSupplier
该实现使用类路径中可用的发现客户端从服务发现中检索可用实例。
我靠难道说,只支持服务发现的方式了吗,没有静态配置的负载均衡了???
找了一大圈,还好找到了
0. SimpleDiscoveryClient
可以结合注册中心使用,也可以静态配置
如果DiscoveryClient
类路径中没有支持服务注册表的SimpleDiscoveryClient
实例,则将使用实例,该实例使用属性来获取有关服务和实例的信息。
有关可用实例的信息应通过以下格式的属性传递给属性: spring.cloud.discovery.client.simple.instances.service1[0].uri=http://s11:8080
,其中 spring.cloud.discovery.client.simple.instances
是公共前缀,然后service1
代表所讨论服务的ID,而[0]
表示实例的索引号(如示例中所示,索引以0
)开头,然后的值uri
是实例可用的实际URI。
spring:
cloud:
gateway:
routes:
- id: lb_laker
uri: lb://lakerservices
predicates:
- Path=/get
discovery:
client:
simple:
instances:
lakerservices:
- uri: http://httpbin.org
- uri: https://httpbin.org
management:
endpoints:
web:
exposure:
include: "*"
1. 在负载均衡算法之间切换
ReactiveLoadBalancer
默认情况下使用的实现是RoundRobinLoadBalancer
。要针对选定的服务或所有服务切换到不同的实现,可以使用自定义LoadBalancer配置机制。
例如,可以通过@LoadBalancerClient
注释传递以下配置以切换为使用RandomLoadBalancer
:
public class CustomLoadBalancerConfiguration {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}
2. 实例健康检查
可以为LoadBalancer启用计划健康检查。为此提供了HealthCheckServiceInstanceListSupplier
。它定期验证委托ServiceInstanceListSupplier提供的实例是否仍然存在,并且只返回健康的实例,除非没有实例—然后返回所有检索到的实例。
在使用
SimpleDiscoveryClient
时,这种机制特别有用。对于由实际服务注册中心支持的客户端,不需要使用它,因为我们在查询外部ServiceDiscovery之后已经获得了健康的实例。
对于每个服务只有少量实例的设置,也建议使用此供应商,以避免重试调用失败的实例。
问题
这里也是踩了蛮多的坑
Spring Cloud Loadbalancer
先上能用的配置,无需增加类。
spring:
cloud:
gateway:
routes:
- id: lb_laker
uri: lb://lakerservices
predicates:
- Path=/**
httpserver:
wiretap: true
httpclient:
wiretap: true
discovery:
client:
simple:
instances:
lakerservices: # 一定要带端口
- uri: http://httpbin.org:80
- uri: https://httpbin.org:443
loadbalancer:
health-check:
path:
lakerservices: /get
initial-delay: 0 #运行状况检查计划程序的初始延迟值。
interval: 5s # 重新运行运行状况检查计划程序的时间间隔。
configurations: health-check #启用预定义的负载平衡器配置。
management:
endpoints:
web:
exposure:
include: "*"
logging:
level:
org.springframework.cloud.gateway: trace
org.springframework.cloud.loadbalancer: trace
org.springframework.web.reactive: trace
问题1:健康检查生效问题
可以参考这个类:LoadBalancerClientConfiguration
1.使用配置文件让其生效【推荐】
spring:
cloud:
loadbalancer:
configurations: health-check #启用预定义的负载平衡器配置。
2.代码模式,必须指定name为service-id,且只对这个service-id生效
@Configuration
@LoadBalancerClient(name = "lakerservices", configuration = CustomLoadBalancerConfiguration.class)
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHealthChecks()
.build(context);
}
}
问题2:实例健康检查配置
指定检查的path
,默认的是/actuator/health
只要返回的Status=200即可。
配置方式如下
serviceid1:/path
path:
serviceid1:/path
serviceid2:/path
spring:
loadbalancer:
health-check:
path:
lakerservices: /get
initial-delay: 0 #运行状况检查计划程序的初始延迟值。
interval: 5s # 重新运行运行状况检查计划程序的时间间隔。
源码跟踪
ReactiveLoadBalancerClientFilter.filter
- ReactiveLoadBalancerClientFilter.choose
- RoundRobinLoadBalancer.choose
- HealthCheckServiceInstanceListSupplier
问题3:实例路径配置问题
因为想简单的使用静态的配置,没加健康检查的时候
- uri: http://httpbin.org
- uri: https://httpbin.org
这样是没问题的,可以正常访问,但是如果加了健康检查就拉了,必须加上端口才可以,如下:
spring:
cloud:
gateway:
routes:
- id: lb_laker
uri: lb://lakerservices
predicates:
- Path=/**
discovery:
client:
simple:
instances:
lakerservices: # 一定要带端口
- uri: http://httpbin.org:80
- uri: https://httpbin.org:443
网关服务
Spring Cloud Gateway
- 网关 Spring Cloud Gateway 简介 入门
- 网关 Spring Cloud Gateway 内置的路由谓词工厂详解(最全的路由策略11种)
- 网关 Spring Cloud Gateway 内置过滤器工厂(超级全30种)
- 网关 Spring Cloud Gateway 内置全局过滤器
- 网关 Spring Cloud Gateway 内置网关过滤器工厂总结
- 网关 Spring Cloud Gateway 两种配置谓词和过滤器的方法
- 网关 Spring Cloud Gateway 监控 actuator
- 网关 Spring Cloud Gateway 自定义路由谓词工厂
- 网关 Spring Cloud Gateway 自定义过滤器(全局过滤器以及网关过滤器)
- 网关 Spring Cloud Gateway 跨域配置
- 网关 Spring Cloud Gateway HTTP超时配置
- 网关 Spring Cloud Gateway 统一全局异常处理
- 用“十幅图“来深刻理解 网关服务 Spring Cloud Gateway
QQ群【837324215】
关注我的公众号【Java大厂面试官】,回复:常用工具、资源等关键词(更多关键词,关注后注意提示信息)获取更多免费资料。
公众号也会持续输出高质量文章,和大家共同进步。