此版本仍在开发中,目前尚不被视为稳定版本。如需最新稳定版本,请使用 Spring Cloud Commons 5.0.1spring-doc.cadn.net.cn

Spring Cloud Commons: 常用抽象

诸如服务发现、负载均衡和断路器等模式可被抽象为一个通用层,供所有 Spring Cloud 客户端使用,且与具体实现(例如使用 Eureka 或 Consul 进行服务发现)无关。spring-doc.cadn.net.cn

@EnableDiscoveryClient注解

Spring Cloud Commons 提供了 @EnableDiscoveryClient 注解。该注解用于查找实现了 DiscoveryClientReactiveDiscoveryClient 接口的实现类,并带有 META-INF/spring.factories 注解。发现客户端的实现类会将一个配置类添加到 spring.factories 中,键为 org.springframework.cloud.client.discovery.EnableDiscoveryClientDiscoveryClient 的示例实现包括 Spring Cloud Netflix EurekaSpring Cloud Consul DiscoverySpring Cloud Zookeeper Discoveryspring-doc.cadn.net.cn

Spring Cloud 将默认提供阻塞式和响应式服务发现客户端。您可以通过设置 spring.cloud.discovery.blocking.enabled=falsespring.cloud.discovery.reactive.enabled=false 轻松禁用阻塞式和/或响应式客户端。若要完全禁用服务发现功能,只需设置 spring.cloud.discovery.enabled=false 即可。spring-doc.cadn.net.cn

默认情况下,DiscoveryClient 的实现会将本地 Spring Boot 服务器自动注册到远程发现服务器。可以通过在 @EnableDiscoveryClient 中设置 autoRegister=false 来禁用此行为。spring-doc.cadn.net.cn

@EnableDiscoveryClient 已不再需要。您可以在类路径中放置一个 DiscoveryClient 的实现,以使 Spring Boot 应用程序注册到服务发现服务器。

健康指标

Commons 自动配置以下 Spring Boot 健康指标。spring-doc.cadn.net.cn

DiscoveryClientHealthIndicator

此健康指标基于当前注册的 DiscoveryClient 个实现。spring-doc.cadn.net.cn

  • 要完全禁用,请设置 spring.cloud.discovery.client.health-indicator.enabled=falsespring-doc.cadn.net.cn

  • 要禁用描述字段,请将 spring.cloud.discovery.client.health-indicator.include-description=false 设置为该字段。否则,它可能会作为汇总的 descriptionHealthIndicator 传播出去。spring-doc.cadn.net.cn

  • 要禁用服务检索,请将 spring.cloud.discovery.client.health-indicator.use-services-query=false 设置为禁用状态。
    默认情况下,该指示器会调用客户端的 getServices 方法。在注册服务数量较多的部署环境中,每次检查时都检索所有服务可能过于昂贵。这将跳过服务检索步骤,转而使用客户端的 probe 方法。spring-doc.cadn.net.cn

DiscoveryCompositeHealthContributor

此复合健康指标基于所有已注册的 DiscoveryHealthIndicator 个 Bean。要禁用它,请设置 spring.cloud.discovery.client.composite-indicator.enabled=falsespring-doc.cadn.net.cn

排序DiscoveryClient实例

DiscoveryClient 接口扩展 Ordered。这在使用多个发现客户端时非常有用,因为它允许您定义返回的发现客户端的顺序,类似于您可以对 Spring 应用程序加载的 Bean 进行排序的方式。默认情况下,任何 DiscoveryClient 的顺序设置为 0。如果您希望为自定义 DiscoveryClient 实现设置不同的顺序,只需重写 getOrder() 方法,使其返回适用于您环境的值即可。除此之外,您还可以通过属性来设置由 Spring Cloud 提供的 DiscoveryClient 实现的顺序,例如 ConsulDiscoveryClientEurekaDiscoveryClientZookeeperDiscoveryClient。要实现此目的,您只需将 spring.cloud.{clientIdentifier}.discovery.order(或针对 Eureka 的 eureka.client.order)属性设置为所需的值。spring-doc.cadn.net.cn

SimpleDiscoveryClient

如果类路径中没有基于服务注册中心的 DiscoveryClient,则将使用 SimpleDiscoveryClient 实例,该实例通过属性获取服务和实例的相关信息。spring-doc.cadn.net.cn

可用实例的信息应通过以下格式的属性传递: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-doc.cadn.net.cn

服务注册中心

Commons 现在提供了一个 ServiceRegistry 接口,该接口提供了诸如 register(Registration)deregister(Registration) 等方法,使您能够提供自定义注册的服务。Registration 是一个标记接口。spring-doc.cadn.net.cn

以下示例展示了 ServiceRegistry 的用法:spring-doc.cadn.net.cn

@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 实现。spring-doc.cadn.net.cn

如果您正在使用 ServiceRegistry 接口,则需要为所使用的 ServiceRegistry 实现传递正确的 Registry 实现。spring-doc.cadn.net.cn

服务注册表自动注册

默认情况下,ServiceRegistry 实现会自动注册运行中的服务。要禁用此行为,您可以设置:spring-doc.cadn.net.cn

  • @EnableDiscoveryClient(autoRegister=false) 用于永久禁用自动注册。spring-doc.cadn.net.cn

  • spring.cloud.service-registry.auto-registration.enabled=false 用于通过配置禁用该行为。spring-doc.cadn.net.cn

服务注册表自动注册事件

当服务自动注册时,会触发两个事件。第一个事件,称为InstancePreRegisteredEvent,在服务注册前触发。第二个事件,称为InstanceRegisteredEvent,在服务注册后触发。您可以注册一个或多个ApplicationListener(监听器)来监听并响应这些事件。spring-doc.cadn.net.cn

这些事件在将 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 支持的状态包括 UPDOWNOUT_OF_SERVICEUNKNOWNspring-doc.cadn.net.cn

Spring RestTemplate 作为负载均衡客户端

您可以配置一个 RestTemplate 以使用负载均衡客户端。要创建一个负载均衡的 RestTemplate,请创建一个 RestTemplate @Bean 并使用 @LoadBalanced 注解限定符,如下例所示:spring-doc.cadn.net.cn

@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 RestTemplate bean is no longer created through auto-configuration.spring-doc.cadn.net.cn

Individual applications must create it.spring-doc.cadn.net.cn

URI 需要使用虚拟主机名(即服务名称,而非主机名)。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

BlockingLoadBalancerClient 用于创建完整的物理地址。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

要使用负载均衡的 RestTemplate,您需要在类路径中包含一个 Spring Cloud LoadBalancer 实现。为了使用它,请将 Spring Cloud LoadBalancer Starters 添加到您的项目中。

多个 RestTemplate 对象

如果您想要一个非负载均衡的 RestTemplate,请创建一个 RestTemplate 类型的 Bean 并将其注入。
要访问负载均衡的 RestTemplate,请在创建您的 @Bean 时使用 @LoadBalanced 限定符,如下例所示:spring-doc.cadn.net.cn

@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,并加上 @LoadBalancedspring-doc.cadn.net.cn

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 需要使用虚拟主机名(即服务名称,而非主机名)。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

BlockingLoadBalancerClient 用于创建完整的物理地址。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

为了利用 Spring Boot 为 RestTemplateBuilder 提供的更多功能(例如,可观测性支持),您可能希望在创建 @LoadBalanced RestTemplateBuilder bean 时使用自动配置的 RestTemplateBuilderConfigurerspring-doc.cadn.net.cn

@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 限定符,如下例所示:spring-doc.cadn.net.cn

@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 注解限定符,如下例所示:spring-doc.cadn.net.cn

@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 需要使用虚拟主机名(即服务名称,而非主机名)。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

BlockingLoadBalancerClient 用于创建完整的物理地址。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

为了利用 Spring Boot 为 RestClient.Builder 提供的更多功能(例如,可观测性支持),您可能希望在创建 @LoadBalanced RestClient.Builder bean 时使用自动配置的 RestClientBuilderConfigurerspring-doc.cadn.net.cn

@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 限定符,如下例所示:spring-doc.cadn.net.cn

@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 注解限定符,如下所示:spring-doc.cadn.net.cn

@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-doc.cadn.net.cn

为了利用 Spring Boot 为 WebClient.Builder 提供的更多功能(例如,可观测性支持),您可能希望在创建 @LoadBalanced WebClient.Builder bean 时使用自动配置的 WebClientCustomizer bean:spring-doc.cadn.net.cn

@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 限定符,如下例所示:spring-doc.cadn.net.cn

@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=truespring-doc.cadn.net.cn

如果您希望禁用 Spring Retry 或 Reactive Retry 的重试逻辑(当类路径中存在这些依赖时),可以设置 spring.cloud.loadbalancer.retry.enabled=falsespring-doc.cadn.net.cn

对于非响应式实现,如果您希望在重试中实现 BackOffPolicy,则需要创建一个类型为 LoadBalancedRetryFactory 的 Bean,并重写 createBackOffPolicy() 方法。spring-doc.cadn.net.cn

对于响应式实现,您只需通过将 spring.cloud.loadbalancer.retry.backoff.enabled 设置为 false 来启用它。spring-doc.cadn.net.cn

您可以设置:spring-doc.cadn.net.cn

  • spring.cloud.loadbalancer.retry.maxRetriesOnSameServiceInstance - 表示应在同一 ServiceInstance(针对每个选定实例分别计数)上重试请求的次数。spring-doc.cadn.net.cn

  • spring.cloud.loadbalancer.retry.maxRetriesOnNextServiceInstance - 表示应重新尝试请求的次数,该请求是新选定的 ServiceInstancespring-doc.cadn.net.cn

  • spring.cloud.loadbalancer.retry.retryableStatusCodes - 在其上始终重试失败请求的状态码。spring-doc.cadn.net.cn

对于响应式实现,您还可以额外设置:
- spring.cloud.loadbalancer.retry.backoff.minBackoff - 设置最小退避持续时间(默认为 5 毫秒)
- spring.cloud.loadbalancer.retry.backoff.maxBackoff - 设置最大退避持续时间(默认为毫秒的最大长整型值)
- spring.cloud.loadbalancer.retry.backoff.jitter - 设置用于计算每次调用实际退避持续时间的抖动值(默认为 0.5)。spring-doc.cadn.net.cn

对于响应式实现,您还可以实现自己的 LoadBalancerRetryPolicy,以对负载均衡调用的重试过程进行更细致的控制。spring-doc.cadn.net.cn

对于两种实现方式,您还可以通过在 spring.cloud.loadbalancer.[serviceId].retry.retryable-exceptions 属性下添加一个异常列表来设置触发响应的异常。如果您这样做,我们会确保将 RetryableStatusCodeExceptions 添加到您提供的异常列表中,以便在可重试的状态码上也进行重试。如果您未通过属性指定任何异常,我们默认使用的异常是 IOExceptionTimeoutExceptionRetryableStatusCodeException。您还可以通过将 spring.cloud.loadbalancer.[serviceId].retry.retry-on-all-exceptions 设置为 true 来启用对所有异常的重试。spring-doc.cadn.net.cn

如果您使用 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 数组,如下例所示:spring-doc.cadn.net.cn

@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-doc.cadn.net.cn

Spring WebFluxWebClient使用ReactorLoadBalancerExchangeFilterFunction

您可以将 WebClient 配置为使用 ReactiveLoadBalancer。如果在项目中添加 Spring Cloud LoadBalancer Starters,且 spring-webflux 在类路径上,则 ReactorLoadBalancerExchangeFilterFunction 将被自动配置。以下示例展示了如何配置一个 WebClient 以使用响应式负载均衡器:spring-doc.cadn.net.cn

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 需要使用虚拟主机名(即服务名称,而非主机名)。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

ReactorLoadBalancer 用于创建完整的物理地址。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

Spring WebFluxWebClient使用非响应式负载均衡客户端

如果 spring-webflux 在类路径中,则会自动配置 LoadBalancerExchangeFilterFunction。不过请注意,其底层使用的是非响应式客户端。以下示例展示了如何配置 WebClient 以使用负载均衡器:spring-doc.cadn.net.cn

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 需要使用虚拟主机名(即服务名称,而非主机名)。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

LoadBalancerClient 用于创建完整的物理地址。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

This approach is now deprecated. We suggest that you use WebFlux with reactive Load-Balancer instead.

忽略网络接口

有时,忽略某些命名的网络接口会很有用,以便将它们从服务发现注册中排除(例如,在 Docker 容器中运行时)。可以通过设置正则表达式列表,来指定需要被忽略的网络接口。以下配置会忽略 docker0 接口以及所有以 veth 开头的接口:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    inetutils:
      ignoredInterfaces:
        - docker0
        - veth.*

您还可以通过使用正则表达式列表强制仅使用指定的网络地址,如下例所示:spring-doc.cadn.net.cn

bootstrap.yml
spring:
  cloud:
    inetutils:
      preferredNetworks:
        - 192.168
        - 10.0

你也可以强制仅使用本地站点地址,如下例所示:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    inetutils:
      useOnlySiteLocalInterfaces: true

有关什么是站点本地地址的更多详情,请参见 Inet4Address.html.isSiteLocalAddress()spring-doc.cadn.net.cn

启用的功能

Spring Cloud Commons 提供了一个 /features 操作端点。此端点返回类路径上可用的功能及其是否已启用的信息。返回的信息包括功能类型、名称、版本和提供商。spring-doc.cadn.net.cn

特征类型

有两种类型的‘特性’:抽象特性和命名特性。spring-doc.cadn.net.cn

抽象功能是指在接口或抽象类中定义的功能,其具体实现由创建的类提供,例如 DiscoveryClientLoadBalancerClientLockService。抽象类或接口用于在上下文中查找该类型的 Bean。当前显示的版本是 bean.getClass().getPackage().getImplementationVersion()spring-doc.cadn.net.cn

命名功能是指那些没有特定实现类的功能。这些功能包括“熔断器”、“API 网关”、“Spring Cloud Bus”等。这些功能需要一个名称和一个 Bean 类型。spring-doc.cadn.net.cn

Declaring features

任何模块都可以声明任意数量的HasFeature个 bean,如下面的示例所示:spring-doc.cadn.net.cn

@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-doc.cadn.net.cn

Spring Cloud 兼容性验证

由于一些用户在设置 Spring Cloud 应用程序时遇到问题,我们决定添加兼容性验证机制。 它将在当前设置与 Spring Cloud 要求不兼容时中断,同时显示报告,显示具体出错内容。spring-doc.cadn.net.cn

当前正在验证Spring Boot版本已添加到类路径。spring-doc.cadn.net.cn

***************************
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-doc.cadn.net.cn