spring cloud 2020.0.1踩坑记录-bootstrap不生效等
使用版本:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.2</version> <relativePath /> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <spring-cloud-release.version>2020.0.1</spring-cloud-release.version> <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version> </properties>
1、bootstrap.yml默认不生效
官方文档有提到(原文传送门):
To use the legacy bootstrap way of connecting to Config Server,bootstrap must be enabled via a property or the
spring-cloud-starter-bootstrap
starter.The property isspring.cloud.bootstrap.enabled=true
. It must be set as a System Property or environment variable.
翻译:想用bootstrap,需要将spring.cloud.bootstrap.enabled设为true(注意这个必须设为系统变量或者环境变量)或 引入一个依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
该依赖会引入一个名为 org.springframework.cloud.bootstrap.marker.Marker 的类 ,进而导致以下判断为假:
进而执行后边的bootstrap文件内容加载逻辑。
2、Spring Cloud Gateway + Nacos 无法发现服务
Gateway已经注册到了nacos,就算访问自己都访问不到,报503 Service Unavailable
原因是Spring Cloud的负载均衡需要单独引入
解决方法,引入以下依赖:
<!--不加这个没法路由,被坑惨--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>
3、如何修改LoadBalancer
想自己写个负载均衡策略,一开始简单看了一下源码(RoundRobinLoadBalancer、LoadBalancerClientConfiguration),复制修改了一下,行不通,name获取到的始终是null
@Configuration
public class MetaRouteRoundRobinLoadBalancerConfiguration { @Bean public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new MetaRouteRoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); } }
后来研究了一下,发现在访问的时候name获取的才不是空,而这个时候 LoadBalancerClientConfiguration中的LoadBalancer才被创建。
看了一下整体的加载过程 、 别人的提问,再加上官网要求我们不要使用@Configuration ,而是使用@LoadBalancerClient
但是@LoadBalancerClient并不够用,需要一个服务一个服务的设置其路由策略,而我想要的是全局默认策略
最后在源码的同一个包下找到了LoadBalancerClients,在里面的注释上找到关键线索
自定义路由解决方案
步骤1、去掉上边的@Configuration
public class MetaRouteRoundRobinLoadBalancerConfiguration { @Bean public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new MetaRouteRoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); } }
步骤2:在入口类上加上注解:
@LoadBalancerClients(defaultConfiguration = {MetaRouteRoundRobinLoadBalancerConfiguration.class})
注意,这里的 MetaRouteRoundRobinLoadBalancer 是我自己定义的,你也可以仿着其它实现自己定义:
(待补充)