跳到主要内容

Spring Cloud Commons:通用抽象

DeepSeek V3 中英对照 Spring Cloud Commons: Common Abstractions

诸如服务发现、负载均衡和断路器等模式适用于一个通用的抽象层,该层可以被所有 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。否则,它可能会作为汇总的 HealthIndicator 的 description 字段冒泡显示。

  • 要禁用服务检索,请设置 spring.cloud.discovery.client.health-indicator.use-services-query=false。默认情况下,指示器会调用客户端的 getServices 方法。在注册了许多服务的部署中,每次检查时检索所有服务的成本可能过高。这将跳过服务检索,转而使用客户端的 probe 方法。

DiscoveryCompositeHealthContributor​

此复合健康指标基于所有已注册的 DiscoveryHealthIndicator 实例。要禁用此功能,请设置 spring.cloud.discovery.client.composite-indicator.enabled=false。

排序 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);
}
}
java

每个 ServiceRegistry 实现都有其自己的 Registry 实现。

  • ZookeeperRegistration 与 ZookeeperServiceRegistry 一起使用

  • EurekaRegistration 与 EurekaServiceRegistry 一起使用

  • ConsulRegistration 与 ConsulServiceRegistry 一起使用

如果你使用的是 ServiceRegistry 接口,你需要为你所使用的 ServiceRegistry 实现传递正确的 Registry 实现。

服务注册自动注册​

默认情况下,ServiceRegistry 实现会自动注册正在运行的服务。要禁用该行为,您可以设置:* @EnableDiscoveryClient(autoRegister=false) 以永久禁用自动注册。* spring.cloud.service-registry.auto-registration.enabled=false 以通过配置禁用该行为。

ServiceRegistry 自动注册事件​

当一个服务自动注册时,将会触发两个事件。第一个事件是 InstancePreRegisteredEvent,在服务注册之前触发。第二个事件是 InstanceRegisteredEvent,在服务注册之后触发。你可以注册一个或多个 ApplicationListener 来监听并响应这些事件。

备注

如果 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;
}
}
java
警告

RestTemplate 的 bean 不再通过自动配置创建。各个应用程序必须自行创建它。

URI 需要使用虚拟主机名称(即服务名称,而非主机名称)。BlockingLoadBalancerClient 用于创建完整的物理地址。

important

要使用负载均衡的 RestTemplate,你需要在类路径中包含一个 Spring Cloud LoadBalancer 实现。将 Spring Cloud LoadBalancer starter 添加到你的项目中以便使用它。

多个 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);
}
}
java
important

注意在前面的示例中,普通的 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 创建负载均衡客户端​

你也可以通过使用 @LoadBalanced 注解来配置一个 RestTemplate,使其使用负载均衡客户端:

@Bean
@LoadBalanced
public RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder();
}
java

这样配置后,RestTemplate 将能够通过负载均衡器来分发请求。

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);
}
}
java

URI 需要使用虚拟主机名(即服务名称,而不是主机名)。BlockingLoadBalancerClient 用于创建完整的物理地址。

为了利用 Spring Boot 为 RestTemplateBuilder 提供的额外功能(例如,可观测性支持),在创建 @LoadBalanced RestTemplateBuilder bean 时,您可能希望使用自动配置的 RestTemplateBuilderConfigurer:

@Configuration
public class MyConfiguration {

@LoadBalanced
RestTemplateBuilder loadBalancedRestTemplateBuilder(RestTemplateBuilderConfigurer configurer) {
return configurer.configure(new RestTemplateBuilder());
}
}
java
important

要使用它,请将 Spring Cloud LoadBalancer 启动器 添加到您的项目中。

多个 RestTemplateBuilder Bean​

如果你想要一个不进行负载均衡的 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);
}
}
java
important

请注意前面示例中在普通的 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);
}
}
java

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());
}
}
java
important

要使用它,请将 Spring Cloud LoadBalancer 启动器 添加到您的项目中。

多个 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);
}
}
java
important

注意在前面的示例中,普通 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);
}
}
java

URI 需要使用虚拟主机名(即服务名称,而不是主机名称)。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;
}
}
java
important

如果你想使用 @LoadBalanced WebClient.Builder,你需要在类路径中包含一个 Spring Cloud LoadBalancer 实现。我们建议你向项目中添加 Spring Cloud LoadBalancer starter。然后,底层将使用 ReactiveLoadBalancer。

多个 WebClient.Builder 对象​

如果你想要一个非负载均衡的 WebClient.Builder,可以创建一个 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);
}
}
java

重试失败的请求​

一个负载均衡的 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 Retries 的阻塞实现时,想要保持之前版本的行为,请将 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();
}
};
}
}
java

如果你想为你的重试功能添加一个或多个 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...
}
}};
}
};
}
}
java

作为负载均衡器客户端的 Spring WebFlux WebClient​

Spring WebFlux 可以与响应式和非响应式的 WebClient 配置一起工作,正如主题所描述的那样:

使用 ReactorLoadBalancerExchangeFilterFunction 的 Spring WebFlux WebClient​

你可以配置 WebClient 以使用 ReactiveLoadBalancer。如果你将 Spring Cloud LoadBalancer starter 添加到你的项目中,并且 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);
}
}
java

URI 需要使用虚拟主机名(即服务名称,而不是主机名)。ReactorLoadBalancer 用于创建完整的物理地址。

使用非响应式负载均衡器客户端的 Spring WebFlux WebClient​

如果 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);
}
}
java

URI 需要使用虚拟主机名(即服务名称,而非主机名)。LoadBalancerClient 用于创建完整的物理地址。

WARN: 此方法现已弃用。我们建议您改用 带有响应式负载均衡器的 WebFlux。

忽略网络接口​

有时,忽略某些命名的网络接口非常有用,以便可以将它们从服务发现注册中排除(例如,在 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()。

HTTP 客户端工厂​

Spring Cloud Commons 提供了用于创建 Apache HTTP 客户端(ApacheHttpClientFactory)和 OK HTTP 客户端(OkHttpClientFactory)的 bean。只有在类路径上存在 OK HTTP jar 时,才会创建 OkHttpClientFactory bean。此外,Spring Cloud Commons 还提供了用于创建这两个客户端所使用的连接管理器的 bean:ApacheHttpClientConnectionManagerFactory 用于 Apache HTTP 客户端,OkHttpClientConnectionPoolFactory 用于 OK HTTP 客户端。如果你想在下游项目中自定义 HTTP 客户端的创建方式,可以提供这些 bean 的自定义实现。此外,如果你提供了一个类型为 HttpClientBuilder 或 OkHttpClient.Builder 的 bean,默认的工厂会将这些构建器作为返回给下游项目的构建器的基础。你也可以通过将 spring.cloud.httpclientfactories.apache.enabled 或 spring.cloud.httpclientfactories.ok.enabled 设置为 false 来禁用这些 bean 的创建。

启用的功能​

Spring Cloud Commons 提供了一个 /features 执行器端点。该端点返回类路径上可用的功能以及它们是否已启用。返回的信息包括功能类型、名称、版本和供应商。

特征类型​

有两种类型的 "features":抽象的和命名的。

抽象特性是指定义了一个接口或抽象类,并由实现类创建的特性,例如 DiscoveryClient、LoadBalancerClient 或 LockService。抽象类或接口用于在上下文中查找该类型的 bean。显示的版本为 bean.getClass().getPackage().getImplementationVersion()。

命名特性是指那些没有特定实现类的特性。这些特性包括“熔断器”(Circuit Breaker)、“API 网关”(API Gateway)、“Spring Cloud 总线”(Spring Cloud Bus)等。这些特性需要一个名称和一个 bean 类型。

声明特性​

任何模块都可以声明任意数量的 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();
}
java

每个这些 bean 都应该放在一个适当保护的 @Configuration 中。

Spring Cloud 兼容性验证​

由于一些用户在设置 Spring Cloud 应用程序时遇到问题,我们决定添加一个兼容性验证机制。如果您当前的设置不符合 Spring Cloud 的要求,该机制将会中断,并生成一份报告,显示具体出了什么问题。

目前我们正在验证您的 classpath 中添加了哪个版本的 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 属性,并使用逗号分隔的兼容 Spring Boot 版本列表。