Spring Cloud Document翻译(二)--Spring Cloud Commons

原文链接:https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/multi/multi__spring_cloud_commons_common_abstractions.html

3. Spring Cloud Commons:共通的抽象

服务发现,负载平衡和断路器等模式是所有Spring Cloud客户端可以使用的公共抽象层,与实现无关(例如,使用Eureka或Consul进行发现)。

3.1 @EnableDiscoveryClient

Spring Cloud Commons提供了@EnableDiscoveryClient注解。这将用META-INF/spring.factories查找DiscoveryClient接口的实现。Discovery Client的实现在spring.factories的org.springframework.cloud.client.discovery.EnableDiscoveryClient key下添加一个配置类。DiscoveryClient实现的例子包括Spring Cloud Netflix EurekaSpring Cloud Consul DiscoverySpring Cloud Zookeeper Discovery

默认情况下,DiscoveryClient的实现类使用远程发现服务器自动注册本地Spring Boot服务器。这种行为可以通过在@EnableDiscoveryClient设置autoRegister=false被禁用。

[注意]

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

3.1.1 健康指示

Commons创建了一个Spring Boot HealthIndicatorDiscoveryClient实现可以通过实现DiscoveryHealthIndicator参与。要禁用复合HealthIndicator,请设置spring.cloud.discovery.client.composite-indicator.enabled=false。一个基本的基于DiscoveryClient的HealthIndicator会被自动配置(DiscoveryClientHealthIndicator)。要禁用它,请设置spring.cloud.discovery.client.health-indicator.enabled=false。要禁用DiscoveryClientHealthIndicator的描述字段,请设置spring.cloud.discovery.client.health-indicator.include-description=false。否则,它会在rolled up HealthIndicator中冒出来描述。

3.1.2 给DiscoveryClient实例排序

DiscoveryClient接口扩展Ordered。这在使用多个DiscoveryClient时很有用,因为它允许您定义返回的DiscoveryClient的顺序,类似于您可以如何排序Spring应用程序加载的bean。默认情况下,任意DiscoveryClient设置的顺序为 0。如果要为自定义DiscoveryClient实现设置不同的顺序,则只需覆盖该getOrder()方法,以便返回适合您的设置的值。除了这个,你可以使用属性来设置Spring Cloud提供的DiscoveryClient实现的顺序,如ConsulDiscoveryClientEurekaDiscoveryClient和 ZookeeperDiscoveryClient。为此,您只需将spring.cloud.{clientIdentifier}.discovery.order(或为Eureka设置eureka.client.order)属性设置为所需的值即可。

3.2 ServiceRegistry

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实现。

3.2.1 ServiceRegistry自动注册

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

ServiceRegistry自动注册事件

当服务自动注册时,将触发两个事件。名为InstancePreRegisteredEvent的第一个事件 在注册服务之前被触发。第二个事件叫做InstanceRegisteredEvent,在服务注册后被触发。您可以注册一个 ApplicationListener(s)来收听并回应这些事件。

[注意]

如果spring.cloud.service-registry.auto-registration.enabled设置为,则不会触发这些事件false

3.2.2 服务注册Actuator端点(Service Registry Actuator Endpoint)

Spring Cloud Commons提供/service-registry执行器端点。此端点依赖于Registration bean,它处于Spring Application Context中。/service-registry使用GET 调用返回Registration的状态。将POST用于具有JSON主体的同一端点会将当前状态更改Registration为新值。JSON主体必须包含status具有首选值的字段。ServiceRegistry更新状态和为状态返回的值时,请参阅您用于允许值的实现的文档。例如,Eureka支持的状态是UPDOWNOUT_OF_SERVICE,和UNKNOWN

 

3.3 Spring RestTemplate作为负载均衡器客户端

RestTemplate可以自动配置为使用ribbon。要创建负载均衡的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 results = restTemplate.getForObject("http://stores/stores", String.class);
        return results;
    }
}
  警告

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

URI需要使用虚拟主机名(即服务名称,而不是主机名)。Ribbon客户端用于创建完整的物理地址。有关如何设置RestTemplate的详细信息,请参见RibbonAutoConfiguration

3.4 Spring WebClient作为负载均衡器客户端

WebClient可以自动配置使用LoadBalancerClient。要创建负载平衡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需要使用虚拟主机名(即服务名称,而不是主机名)。Ribbon客户端用于创建完整的物理地址。

3.4.1重试失败的请求

负载均衡的RestTemplate可以被配置为重试失败的请求。默认情况下,此逻辑被禁用。您可以通过添加Spring Retry到应用程序的类路径来启用它。负载平衡RestTemplate拥有一些与重试失败请求相关的Ribbon配置值。您可以使用client.ribbon.MaxAutoRetriesclient.ribbon.MaxAutoRetriesNextServerclient.ribbon.OkToRetryOnAllOperations属性。如果要在类路径上使用Spring Retry禁用重试逻辑,则可以设置spring.cloud.loadbalancer.retry.enabled=false。有关这些属性的说明,请参阅Ribbon文档

如果要在重试中实现BackOffPolicy,则需要创建 LoadBalancedRetryFactory类型的bean并覆盖该createBackOffPolicy方法:

Configuration
public class MyConfiguration {
    @Bean
    LoadBalancedRetryFactory retryFactory() {
        return new LoadBalancedRetryFactory() {
            @Override
            public BackOffPolicy createBackOffPolicy(String service) {
        		return new ExponentialBackOffPolicy();
        	}
        };
    }
}
[注意]

在上面的示例中的client,应被替换为你的Ribbon客户端的名称。

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

3.5 多个RestTemplate对象

如果你想要一个不负载平衡的RestTemplate,创建一个RestTemplatebean并注入它。要访问负载平衡的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("https://example.com", String.class);
    }
}
[重要] 重要

请注意在前面示例中给简单RestTemplate声明使用@Primary注解,用来消除@Autowired注入产生的歧义。

[Tip]

如果您看到错误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

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

WebClient可以配置为使用LoadBalancerClient。如果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用于创建一个完整的物理地址。

3.7忽略网络接口

有时,忽略某些名称的网络接口以便从服务发现注册中排除它们(例如,在Docker容器中运行时)是有用的。可以设置一个正则表达式列表以使所需的网络接口被忽略。以下配置忽略docker0接口和所有以veth开头的接口:

application.yml。 

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

您还可以使用正则表达式列表强制仅使用指定的网络地址,如以下示例所示:

bootstrap.yml。 

spring:
  cloud:
    inetutils:
      preferredNetworks:
        - 192.168
        - 10.0

您还可以强制仅使用站点本地地址,如以下示例所示:.application.yml

spring:
  cloud:
    inetutils:
      useOnlySiteLocalInterfaces: true

有关构成站点本地地址的更多详细信息,请参阅Inet4Address.html.isSiteLocalAddress()

3.8 HTTP客户端工厂

Spring Cloud Commons提供了用于创建Apache HTTP客户端(ApacheHttpClientFactory)和OK HTTP客户端(OkHttpClientFactory)的bean 。仅当OK HTTP jar在classpath中OkHttpClientFactory才能被创建。此外,Spring Cloud Commons提供了用于创建两个客户端使用的连接管理器的bean:

   ApacheHttpClientConnectionManagerFactory 用于Apache HTTP客户端

   OkHttpClientConnectionPoolFactory 用于OK HTTP客户端。

如果要自定义在下游项目中创建HTTP客户端的方式,可以提供自己的这些bean的实现。此外,如果您提供HttpClientBuilderOkHttpClient.Builder类型的Bean,默认的工厂使用这些Builder作为Builder的基础返回给下游项目。您还可以通过设置spring.cloud.httpclientfactories.apache.enabledspring.cloud.httpclientfactories.ok.enabled为false,来禁用这些bean的创建。

3.9启用特性

Spring Cloud Commons提供/features actuator端点。此端点返回类路径上可用的功能以及它们是否已启用。返回的信息包括功能类型,名称,版本和供应商。

3.9.1特性类型

有两种类型的'特性':抽象和命名。

抽象特性是指接口或抽象类的定义以及它们的一个实现,例如DiscoveryClientLoadBalancerClient,或LockService。抽象类或接口用于在上下文中查找该类型的bean。下面的代码可以显示版本。bean.getClass().getPackage().getImplementationVersion()

命名特性是指一些没有特定实现类的特性,例如“断路器”,“API网关”,“Spring Cloud Bus”等。这些功能需要一个名称和bean类型。

3.9.2声明特性

任何模块都可以声明任意数量的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(Foo.class)
      .namedFeature(new NamedFeature("Bar Feature", Bar.class))
      .abstractFeature(Baz.class)
      .build();
}

这些Bean中的每一个都应该得到@Configuration适当的保护。

3.10 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.enabledfalse。如果要覆盖兼容的Spring Boot版本,只需使用逗号分隔的兼容Spring Boot版本的列表设置该spring.cloud.compatibility-verifier.compatible-boot-versions属性即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章