Spring Cloud Commons: 常用抽象
诸如服务发现、负载均衡和断路器等模式可被抽象为一个通用层,供所有 Spring Cloud 客户端使用,且与具体实现(例如使用 Eureka 或 Consul 进行服务发现)无关。
这@EnableDiscoveryClient注解
Spring Cloud Commons 提供了 @EnableDiscoveryClient 注解。该注解用于查找实现了 DiscoveryClient 和 ReactiveDiscoveryClient 接口的实现类,并带有 META-INF/spring.factories 注解。发现客户端的实现类会将一个配置类添加到 spring.factories 中,键为 org.springframework.cloud.client.discovery.EnableDiscoveryClient。DiscoveryClient 的示例实现包括 Spring Cloud Netflix Eureka、Spring Cloud Consul Discovery 和 Spring Cloud Zookeeper Discovery。
Spring Cloud 将默认提供阻塞式和响应式服务发现客户端。您可以通过设置 spring.cloud.discovery.blocking.enabled=false 或 spring.cloud.discovery.reactive.enabled=false 轻松禁用阻塞式和/或响应式客户端。若要完全禁用服务发现功能,只需设置 spring.cloud.discovery.enabled=false 即可。
默认情况下,DiscoveryClient 的实现会将本地 Spring Boot 服务器自动注册到远程发现服务器。可以通过在 @EnableDiscoveryClient 中设置 autoRegister=false 来禁用此行为。
@EnableDiscoveryClient 已不再需要。您可以在类路径中放置一个 DiscoveryClient 的实现,以使 Spring Boot 应用程序注册到服务发现服务器。 |
健康指标
Commons 自动配置以下 Spring Boot 健康指标。
DiscoveryClientHealthIndicator
此健康指标基于当前注册的 DiscoveryClient 个实现。
-
要完全禁用,请设置
spring.cloud.discovery.client.health-indicator.enabled=false。 -
要禁用描述字段,请将
spring.cloud.discovery.client.health-indicator.include-description=false设置为该字段。否则,它可能会作为汇总的description的HealthIndicator传播出去。 -
要禁用服务检索,请将
spring.cloud.discovery.client.health-indicator.use-services-query=false设置为禁用状态。
默认情况下,该指示器会调用客户端的getServices方法。在注册服务数量较多的部署环境中,每次检查时都检索所有服务可能过于昂贵。这将跳过服务检索步骤,转而使用客户端的probe方法。
排序DiscoveryClient实例
DiscoveryClient 接口扩展 Ordered。这在使用多个发现客户端时非常有用,因为它允许您定义返回的发现客户端的顺序,类似于您可以对 Spring 应用程序加载的 Bean 进行排序的方式。默认情况下,任何 DiscoveryClient 的顺序设置为 0。如果您希望为自定义 DiscoveryClient 实现设置不同的顺序,只需重写 getOrder() 方法,使其返回适用于您环境的值即可。除此之外,您还可以通过属性来设置由 Spring Cloud 提供的 DiscoveryClient 实现的顺序,例如 ConsulDiscoveryClient、EurekaDiscoveryClient 和 ZookeeperDiscoveryClient。要实现此目的,您只需将 spring.cloud.{clientIdentifier}.discovery.order(或针对 Eureka 的 eureka.client.order)属性设置为所需的值。
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。
服务注册中心
Commons 现在提供了一个 ServiceRegistry 接口,该接口提供了诸如 register(Registration) 和 deregister(Registration) 等方法,使您能够提供自定义注册的服务。Registration 是一个标记接口。
以下示例展示了 ServiceRegistry 的用法:
@Configuration
@EnableDiscoveryClient(autoRegister=false)
public class MyConfiguration {
private ServiceRegistry registry;
public MyConfiguration(ServiceRegistry registry) {
this.registry = registry;
}
// called through some external process, such as an event or a custom actuator endpoint
public void register() {
Registration registration = constructRegistration();
this.registry.register(registration);
}
}
每个 ServiceRegistry 实现都有其自身的 Registry 实现。
-
ZookeeperRegistration与ZookeeperServiceRegistry一起使用 -
EurekaRegistration与EurekaServiceRegistry一起使用 -
ConsulRegistration与ConsulServiceRegistry一起使用
如果您正在使用 ServiceRegistry 接口,则需要为所使用的 ServiceRegistry 实现传递正确的 Registry 实现。
服务注册表自动注册
默认情况下,ServiceRegistry 实现会自动注册运行中的服务。要禁用此行为,您可以设置:
-
@EnableDiscoveryClient(autoRegister=false)用于永久禁用自动注册。 -
spring.cloud.service-registry.auto-registration.enabled=false用于通过配置禁用该行为。
服务注册表指标端点
Spring Cloud Commons 提供了一个 /serviceregistry 指标端点。该端点依赖于 Spring 应用上下文中的一个 Registration Bean。通过 GET 请求调用 /serviceregistry 可返回 Registration 的状态。使用 POST 请求向同一端点发送包含 JSON 数据体的请求,可将当前 Registration 的状态更改为新值。JSON 数据体必须包含 status 字段,并指定期望的新值。请参阅您所使用的 ServiceRegistry 实现的文档,以了解更新状态时允许的取值范围以及状态返回值。例如,Eureka 支持的状态包括 UP、DOWN、OUT_OF_SERVICE 和 UNKNOWN。
Spring RestTemplate 作为负载均衡客户端
您可以配置一个 RestTemplate 以使用负载均衡客户端。要创建一个负载均衡的 RestTemplate,请创建一个 RestTemplate @Bean 并使用 @LoadBalanced 注解限定符,如下例所示:
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
public class MyClass {
@Autowired
private RestTemplate restTemplate;
public String doOtherStuff() {
String result = restTemplate.getForObject("http://stores/stores", String.class);
return result;
}
}
A Individual applications must create it. |
URI 需要使用虚拟主机名(即服务名称,而非主机名)。
BlockingLoadBalancerClient 用于创建完整的物理地址。
要使用负载均衡的 RestTemplate,您需要在类路径中包含一个 Spring Cloud LoadBalancer 实现。为了使用它,请将 Spring Cloud LoadBalancer Starters 添加到您的项目中。 |
多个 RestTemplate 对象
如果您想要一个非负载均衡的 RestTemplate,请创建一个 RestTemplate 类型的 Bean 并将其注入。
要访问负载均衡的 RestTemplate,请在创建您的 @Bean 时使用 @LoadBalanced 限定符,如下例所示:
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
RestTemplate loadBalanced() {
return new RestTemplate();
}
@Primary
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
public class MyClass {
@Autowired
private RestTemplate restTemplate;
@Autowired
@LoadBalanced
private RestTemplate loadBalanced;
public String doOtherStuff() {
return loadBalanced.getForObject("http://stores/stores", String.class);
}
public String doStuff() {
return restTemplate.getForObject("http://example.com", String.class);
}
}
注意在前一个示例中,对普通 RestTemplate 声明使用了 @Primary 注解,以消除对未限定的 @Autowired 注入的歧义。 |
如果您看到诸如 java.lang.IllegalArgumentException: Can not set org.springframework.web.client.RestTemplate field com.my.app.Foo.restTemplate to com.sun.proxy.$Proxy89 这样的错误,请尝试注入 RestOperations 或设置 spring.aop.proxyTargetClass=true。 |
使用@LoadBalanced RestTemplateBuilder创建负载均衡器客户端
您还可以配置一个 RestTemplate,以通过使用负载均衡客户端来注解一个 RestTemplateBuilder Bean,并加上 @LoadBalanced:
import org.springframework.boot.web.client.RestTemplateBuilder;@Configuration
public class MyConfiguration {
@Bean
@LoadBalanced
RestTemplateBuilder loadBalancedRestTemplateBuilder() {
return new RestTemplateBuilder();
}
}
public class MyClass {
private final RestTemplate restTemplate;
MyClass(@LoadBalanced RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
public String getStores() {
return restTemplate.getForObject("http://stores/stores", String.class);
}
}
URI 需要使用虚拟主机名(即服务名称,而非主机名)。
BlockingLoadBalancerClient 用于创建完整的物理地址。
为了利用 Spring Boot 为 RestTemplateBuilder 提供的更多功能(例如,可观测性支持),您可能希望在创建 @LoadBalanced RestTemplateBuilder bean 时使用自动配置的 RestTemplateBuilderConfigurer:
@Configuration
public class MyConfiguration {
@LoadBalanced
RestTemplateBuilder loadBalancedRestTemplateBuilder(RestTemplateBuilderConfigurer configurer) {
return configurer.configure(new RestTemplateBuilder());
}
}
| 要使用它,请将 Spring Cloud LoadBalancer Starters 添加到您的项目中。 |
多个RestTemplateBuilderBean
如果您想要一个非负载均衡的 RestTemplateBuilder,请创建一个 RestTemplateBuilder 类型的 Bean 并将其注入。
要访问负载均衡的 RestTemplateBuilder,请在创建您的 @Bean 时使用 @LoadBalanced 限定符,如下例所示:
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
RestTemplateBuilder loadBalancedRestTemplateBuilder() {
return new RestTemplateBuilder();
}
@Primary
@Bean
RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder();
}
}
public class MyClass {
@Autowired
private RestTemplateBuilder restTemplateBuilder;
@Autowired
@LoadBalanced
private RestTemplateBuilder loadBalanced;
public String doOtherStuff() {
return loadBalanced.getForObject("http://stores/stores", String.class);
}
public String doStuff() {
return restTemplateBuilder.build().getForObject("http://example.com", String.class);
}
}
注意在前一个示例中,对普通 RestTemplateBuilder 声明使用了 @Primary 注解,以消除对未限定的 @Autowired 注入的歧义。 |
Spring RestClient 作为负载均衡客户端
您可以配置一个 RestClient 以使用负载均衡客户端。要创建一个负载均衡的 RestClient,请创建一个 RestClient.Builder @Bean 并使用 @LoadBalanced 注解限定符,如下例所示:
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
RestClient.Builder restClientBuilder() {
return RestClient.builder();
}
}
public class MyClass {
@Autowired
private RestClient.Builder restClientBuilder;
public String doOtherStuff() {
return restClientBuilder.build().get().uri(URI.create("http://stores/stores")).retrieve().body(String.class);
}
}
URI 需要使用虚拟主机名(即服务名称,而非主机名)。
BlockingLoadBalancerClient 用于创建完整的物理地址。
为了利用 Spring Boot 为 RestClient.Builder 提供的更多功能(例如,可观测性支持),您可能希望在创建 @LoadBalanced RestClient.Builder bean 时使用自动配置的 RestClientBuilderConfigurer:
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
RestClient.Builder restClientBuilder(RestClientBuilderConfigurer configurer) {
return configurer.configure(RestClient.builder());
}
}
| 要使用它,请将 Spring Cloud LoadBalancer Starters 添加到您的项目中。 |
多个RestClient.Builder对象
如果您想要一个非负载均衡的 RestClient.Builder,请创建一个 RestClient.Builder 类型的 Bean 并将其注入。
要访问负载均衡的 RestClient.Builder,请在创建您的 @Bean 时使用 @LoadBalanced 限定符,如下例所示:
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
RestClient.Builder loadBalanced() {
return RestClient.builder();
}
@Primary
@Bean
RestClient.Builder restClientBuilder() {
return RestClient.builder();
}
}
public class MyClass {
@Autowired
private RestClient.Builder restClientBuilder;
@Autowired
@LoadBalanced
private RestClient.Builder loadBalanced;
public String doOtherStuff() {
return loadBalanced.build().get().uri("http://stores/stores")
.retrieve().body(String.class);
}
public String doStuff() {
return restClientBuilder.build().get().uri("http://example.com")
.retrieve().body(String.class);
}
}
注意在前一个示例中,对普通 RestClient.Builder 声明使用了 @Primary 注解,以消除对未限定的 @Autowired 注入的歧义。 |
Spring WebClient 作为负载均衡客户端
您可以将 WebClient 配置为自动使用负载均衡客户端。要创建一个负载均衡的 WebClient,请创建一个 WebClient.Builder @Bean 并使用 @LoadBalanced 注解限定符,如下所示:
@Configuration
public class MyConfiguration {
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}
public class MyClass {
@Autowired
private WebClient.Builder webClientBuilder;
public Mono<String> doOtherStuff() {
return webClientBuilder.build().get().uri("http://stores/stores")
.retrieve().bodyToMono(String.class);
}
}
URI 需要使用虚拟主机名(即服务名称,而非主机名)。</p><p>Spring Cloud LoadBalancer 用于创建完整的物理地址。
为了利用 Spring Boot 为 WebClient.Builder 提供的更多功能(例如,可观测性支持),您可能希望在创建 @LoadBalanced WebClient.Builder bean 时使用自动配置的 WebClientCustomizer bean:
@Configuration
public class MyConfiguration {
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder(ObjectProvider<WebClientCustomizer> customizerProvider) {
WebClient.Builder builder = WebClient.builder();
customizerProvider.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder;
}
}
如果您想使用 @LoadBalanced WebClient.Builder,则需要在类路径中包含 Spring Cloud LoadBalancer 实现。我们建议您向项目中添加 Spring Cloud LoadBalancer Starters。之后,ReactiveLoadBalancer 将在底层被使用。 |
多个WebClient.Builder对象
如果您想要一个非负载均衡的 WebClient.Buider,请创建一个 WebClient 类型的 Bean 并将其注入。
要访问负载均衡的 WebClient.Builder,请在创建您的 @Bean 时使用 @LoadBalanced 限定符,如下例所示:
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
WebClient.Builder loadBalanced() {
return WebClient.builder();
}
@Primary
@Bean
WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
public class MyClass {
@Autowired
private WebClient.Builder webClientBuilder;
@Autowired
@LoadBalanced
private WebClient.Builder loadBalanced;
public Mono<String> doOtherStuff() {
return loadBalanced.build().get().uri("http://stores/stores")
.retrieve().bodyToMono(String.class);
}
public Mono<String> doStuff() {
return webClientBuilder.build().get().uri("http://example.com")
.retrieve().bodyToMono(String.class);
}
}
重试失败的请求
负载均衡的 RestTemplate 可以配置为重试失败的请求。默认情况下,此逻辑处于禁用状态。对于非响应式版本(使用 RestTemplate),您可以通过将 Spring Retry 添加到应用程序类路径中来启用它。对于响应式版本(使用 WebTestClient),您需要设置 spring.cloud.loadbalancer.retry.enabled=true。
如果您希望禁用 Spring Retry 或 Reactive Retry 的重试逻辑(当类路径中存在这些依赖时),可以设置 spring.cloud.loadbalancer.retry.enabled=false。
对于非响应式实现,如果您希望在重试中实现 BackOffPolicy,则需要创建一个类型为 LoadBalancedRetryFactory 的 Bean,并重写 createBackOffPolicy() 方法。
对于响应式实现,您只需通过将 spring.cloud.loadbalancer.retry.backoff.enabled 设置为 false 来启用它。
您可以设置:
-
spring.cloud.loadbalancer.retry.maxRetriesOnSameServiceInstance- 表示应在同一ServiceInstance(针对每个选定实例分别计数)上重试请求的次数。 -
spring.cloud.loadbalancer.retry.maxRetriesOnNextServiceInstance- 表示应重新尝试请求的次数,该请求是新选定的ServiceInstance -
spring.cloud.loadbalancer.retry.retryableStatusCodes- 在其上始终重试失败请求的状态码。
对于响应式实现,您还可以额外设置:
- spring.cloud.loadbalancer.retry.backoff.minBackoff - 设置最小退避持续时间(默认为 5 毫秒)
- spring.cloud.loadbalancer.retry.backoff.maxBackoff - 设置最大退避持续时间(默认为毫秒的最大长整型值)
- spring.cloud.loadbalancer.retry.backoff.jitter - 设置用于计算每次调用实际退避持续时间的抖动值(默认为 0.5)。
对于响应式实现,您还可以实现自己的 LoadBalancerRetryPolicy,以对负载均衡调用的重试过程进行更细致的控制。
对于两种实现方式,您还可以通过在 spring.cloud.loadbalancer.[serviceId].retry.retryable-exceptions 属性下添加一个异常列表来设置触发响应的异常。如果您这样做,我们会确保将 RetryableStatusCodeExceptions 添加到您提供的异常列表中,以便在可重试的状态码上也进行重试。如果您未通过属性指定任何异常,我们默认使用的异常是 IOException、TimeoutException 和 RetryableStatusCodeException。您还可以通过将 spring.cloud.loadbalancer.[serviceId].retry.retry-on-all-exceptions 设置为 true 来启用对所有异常的重试。
如果您使用 Spring 重试的阻塞实现,若希望保持之前版本的行为,请将 spring.cloud.loadbalancer.[serviceId].retry.retry-on-all-exceptions 设置为 true,因为这曾是阻塞实现的默认模式。 |
单个负载均衡客户端可单独配置,其属性与上文所述相同,但前缀为 spring.cloud.loadbalancer.clients.<clientId>.*,其中 clientId 是负载均衡器的名称。 |
对于负载均衡重试,默认情况下,我们会将 ServiceInstanceListSupplier Bean 包装在 RetryAwareServiceInstanceListSupplier 中,以从之前选择的不同实例中进行选择(如果可用)。您可以通过将 spring.cloud.loadbalancer.retry.avoidPreviousInstance 的值设置为 false 来禁用此行为。 |
@Configuration
public class MyConfiguration {
@Bean
LoadBalancedRetryFactory retryFactory() {
return new LoadBalancedRetryFactory() {
@Override
public BackOffPolicy createBackOffPolicy(String service) {
return new ExponentialBackOffPolicy();
}
};
}
}
如果您希望为重试功能添加一个或多个 RetryListener 实现,您需要创建一个类型为 LoadBalancedRetryListenerFactory 的 Bean,并返回您希望为特定服务使用的 RetryListener 数组,如下例所示:
@Configuration
public class MyConfiguration {
@Bean
LoadBalancedRetryListenerFactory retryListenerFactory() {
return new LoadBalancedRetryListenerFactory() {
@Override
public RetryListener[] createRetryListeners(String service) {
return new RetryListener[]{new RetryListener() {
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
//TODO Do you business...
return true;
}
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
//TODO Do you business...
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
//TODO Do you business...
}
}};
}
};
}
}
Spring WebFluxWebClient作为负载均衡客户端
Spring WebFlux 可以与响应式和非响应式 WebClient 配置一起使用,如各主题所述:
Spring WebFluxWebClient使用ReactorLoadBalancerExchangeFilterFunction
您可以将 WebClient 配置为使用 ReactiveLoadBalancer。如果在项目中添加 Spring Cloud LoadBalancer Starters,且 spring-webflux 在类路径上,则 ReactorLoadBalancerExchangeFilterFunction 将被自动配置。以下示例展示了如何配置一个 WebClient 以使用响应式负载均衡器:
public class MyClass {
@Autowired
private ReactorLoadBalancerExchangeFilterFunction lbFunction;
public Mono<String> doOtherStuff() {
return WebClient.builder().baseUrl("http://stores")
.filter(lbFunction)
.build()
.get()
.uri("/stores")
.retrieve()
.bodyToMono(String.class);
}
}
URI 需要使用虚拟主机名(即服务名称,而非主机名)。
ReactorLoadBalancer 用于创建完整的物理地址。
Spring WebFluxWebClient使用非响应式负载均衡客户端
如果 spring-webflux 在类路径中,则会自动配置 LoadBalancerExchangeFilterFunction。不过请注意,其底层使用的是非响应式客户端。以下示例展示了如何配置 WebClient 以使用负载均衡器:
public class MyClass {
@Autowired
private LoadBalancerExchangeFilterFunction lbFunction;
public Mono<String> doOtherStuff() {
return WebClient.builder().baseUrl("http://stores")
.filter(lbFunction)
.build()
.get()
.uri("/stores")
.retrieve()
.bodyToMono(String.class);
}
}
URI 需要使用虚拟主机名(即服务名称,而非主机名)。
LoadBalancerClient 用于创建完整的物理地址。
| This approach is now deprecated. We suggest that you use WebFlux with reactive Load-Balancer instead. |
忽略网络接口
有时,忽略某些命名的网络接口会很有用,以便将它们从服务发现注册中排除(例如,在 Docker 容器中运行时)。可以通过设置正则表达式列表,来指定需要被忽略的网络接口。以下配置会忽略 docker0 接口以及所有以 veth 开头的接口:
spring:
cloud:
inetutils:
ignoredInterfaces:
- docker0
- veth.*
您还可以通过使用正则表达式列表强制仅使用指定的网络地址,如下例所示:
spring:
cloud:
inetutils:
preferredNetworks:
- 192.168
- 10.0
你也可以强制仅使用本地站点地址,如下例所示:
spring:
cloud:
inetutils:
useOnlySiteLocalInterfaces: true
有关什么是站点本地地址的更多详情,请参见 Inet4Address.html.isSiteLocalAddress()。
启用的功能
Spring Cloud Commons 提供了一个 /features 操作端点。此端点返回类路径上可用的功能及其是否已启用的信息。返回的信息包括功能类型、名称、版本和提供商。
特征类型
有两种类型的‘特性’:抽象特性和命名特性。
抽象功能是指在接口或抽象类中定义的功能,其具体实现由创建的类提供,例如 DiscoveryClient、LoadBalancerClient 或 LockService。抽象类或接口用于在上下文中查找该类型的 Bean。当前显示的版本是 bean.getClass().getPackage().getImplementationVersion()。
命名功能是指那些没有特定实现类的功能。这些功能包括“熔断器”、“API 网关”、“Spring Cloud Bus”等。这些功能需要一个名称和一个 Bean 类型。
Declaring features
任何模块都可以声明任意数量的HasFeature个 bean,如下面的示例所示:
@Bean
public HasFeatures commonsFeatures() {
return HasFeatures.abstractFeatures(DiscoveryClient.class, LoadBalancerClient.class);
}
@Bean
public HasFeatures consulFeatures() {
return HasFeatures.namedFeatures(
new NamedFeature("Spring Cloud Bus", ConsulBusAutoConfiguration.class),
new NamedFeature("Circuit Breaker", HystrixCommandAspect.class));
}
@Bean
HasFeatures localFeatures() {
return HasFeatures.builder()
.abstractFeature(Something.class)
.namedFeature(new NamedFeature("Some Other Feature", Someother.class))
.abstractFeature(Somethingelse.class)
.build();
}
这些 bean 中的每一个都应该放在一个适当保护的 @Configuration 里。
Spring Cloud 兼容性验证
由于一些用户在设置 Spring Cloud 应用程序时遇到问题,我们决定添加兼容性验证机制。 它将在当前设置与 Spring Cloud 要求不兼容时中断,同时显示报告,显示具体出错内容。
当前正在验证Spring Boot版本已添加到类路径。
报表范例
*************************** APPLICATION FAILED TO START *************************** Description: Your project setup is incompatible with our requirements due to following reasons: - Spring Boot [2.1.0.RELEASE] is not compatible with this Spring Cloud release train Action: Consider applying the following actions: - Change Spring Boot version to one of the following versions [1.2.x, 1.3.x] . You can find the latest Spring Boot versions here [https://spring.io/projects/spring-boot#learn]. If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [https://spring.io/projects/spring-cloud#overview] and check the [Release Trains] section.
要禁用此功能,请将 spring.cloud.compatibility-verifier.enabled 设置为 false。 若要覆盖兼容的 Spring Boot 版本,请使用逗号分隔的列表设置 spring.cloud.compatibility-verifier.compatible-boot-versions 属性。