资讯专栏INFORMATION COLUMN

Spring Cloud 参考文档(Spring Cloud Commons:通用的抽象)

yangrd / 1391人阅读

摘要:通用的抽象服务发现负载均衡和断路器等模式适用于所有客户端都可以使用的通用抽象层,独立于实现例如,使用或发现。重试失败的请求可以将负载均衡的配置为重试失败的请求,默认情况下,禁用此逻辑,你可以通过将添加到应用程序的类路径来启用它。

Spring Cloud Commons:通用的抽象

服务发现、负载均衡和断路器等模式适用于所有Spring Cloud客户端都可以使用的通用抽象层,独立于实现(例如,使用Eureka或Consul发现)。

@EnableDiscoveryClient

Spring Cloud Commons提供@EnableDiscoveryClient注解,这将使用META-INF/spring.factories查找DiscoveryClient接口的实现。Discovery Client的实现将配置类添加到org.springframework.cloud.client.discovery.EnableDiscoveryClient键下的spring.factoriesDiscoveryClient实现的示例包括Spring Cloud Netflix Eureka,Spring Cloud Consul Discovery和Spring Cloud Zookeeper Discovery。

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

@EnableDiscoveryClient已不再需要,你可以在类路径上放置DiscoveryClient实现,以使Spring Boot应用程序向服务发现服务器注册。
健康指示器

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,要禁用DiscoveryClientHealthIndicatordescription字段,请设置spring.cloud.discovery.client.health-indicator.include-description=false,否则,它可能会像卷起的HealthIndicatordescription一样冒出来。

排序DiscoveryClient实例

DiscoveryClient接口扩展了Ordered,这在使用多个发现客户端时很有用,因为它允许你定义返回的发现客户端的顺序,类似于你可以如何排序Spring应用程序加载的bean。默认情况下,任何DiscoveryClient的顺序都设置为0,如果要为自定义DiscoveryClient实现设置不同的顺序,只需重写getOrder()方法,以便它返回适合你的设置的值。除此之外,你还可以使用属性来设置Spring Cloud提供的DiscoveryClient实现的顺序,其中包括ConsulDiscoveryClientEurekaDiscoveryClientZookeeperDiscoveryClient,为此,你只需将spring.cloud.{clientIdentifier}.discovery.order(或Eureka的eureka.client.order)属性设置为所需的值。

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

ZookeeperRegistrationZookeeperServiceRegistry一起使用

EurekaRegistrationEurekaServiceRegistry一起使用

ConsulRegistrationConsulServiceRegistry一起使用

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

ServiceRegistry自动注册

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

ServiceRegistry自动注册事件

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

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

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

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

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 doOtherStuff() {
        return webClientBuilder.build().get().uri("http://stores/stores")
                        .retrieve().bodyToMono(String.class);
    }
}

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

重试失败的请求

可以将负载均衡的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  boolean open(RetryContext context, RetryCallback callback) {
                        //TODO Do you business...
                        return true;
                    }

                    @Override
                     public  void close(RetryContext context, RetryCallback callback, Throwable throwable) {
                        //TODO Do you business...
                    }

                    @Override
                    public  void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
                        //TODO Do you business...
                    }
                }};
            }
        };
    }
}
多个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
Spring WebFlux WebClient作为负载均衡客户端

可以将WebClient配置为使用LoadBalancerClient,如果spring-webflux位于类路径上,则自动配置LoadBalancerExchangeFilterFunction,以下示例显示如何配置WebClient以使用负载均衡:

public class MyClass {
    @Autowired
    private LoadBalancerExchangeFilterFunction lbFunction;

    public Mono doOtherStuff() {
        return WebClient.builder().baseUrl("http://stores")
            .filter(lbFunction)
            .build()
            .get()
            .uri("/stores")
            .retrieve()
            .bodyToMono(String.class);
    }
}

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

忽略网络接口

有时,忽略某些命名的网络接口以便从Service Discovery注册中排除它们(例如,在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()。

HTTP客户端工厂

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

启用特性

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

特性类型

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

抽象特性是定义接口或抽象类并创建实现(如DiscoveryClientLoadBalancerClientLockService)的特性,抽象类或接口用于在上下文中查找该类型的bean,显示的版本是bean.getClass().getPackage().getImplementationVersion()

命名特性是没有他们实现的特定类的特性,例如“断路器”,“API网关”,“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(Foo.class)
      .namedFeature(new NamedFeature("Bar Feature", Bar.class))
      .abstractFeature(Baz.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 Boot版本列表设置spring.cloud.compatibility-verifier.compatible-boot-versions属性。

上一篇:Spring Cloud Context:应用程序上下文服务 下一篇:Spring Cloud Config快速入门

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77560.html

相关文章

  • Spring Cloud 参考文档Spring Cloud Config快速入门)

    摘要:快速入门这个快速入门使用的服务器和客户端。属性在端点中显示为高优先级属性源,如以下示例所示。名为的属性源包含值为且具有最高优先级的属性。属性源名称中的是存储库,而不是配置服务器。 Spring Cloud Config快速入门 这个快速入门使用Spring Cloud Config Server的服务器和客户端。 首先,启动服务器,如下所示: $ cd spring-cloud-con...

    gekylin 评论0 收藏0
  • SpringCloud核心教程 | 第三篇:服务注册与发现 Eureka篇

    摘要:下一篇介绍基于的服务注册与调用。服务提供者工程配置这里服务提供者是使用之前进阶教程第三篇整合连接池以及监控改造而来,这里一样的部分就不再重复说明,下面将说明新增的部分。 Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分...

    scq000 评论0 收藏0
  • Spring Cloud 参考文档Spring Cloud Context:应用程序上下文服务)

    摘要:它们的优先级低于或以及作为创建应用程序过程的正常部分添加到子级的任何其他属性源。为引导配置类使用单独的包名称,并确保或注解的配置类尚未涵盖该名称。在这种情况下,它会在刷新时重建,并重新注入其依赖项,此时,它们将从刷新的重新初始化。 Spring Cloud Context:应用程序上下文服务 Spring Boot有一个关于如何使用Spring构建应用程序的主见,例如,它具有通用配置文...

    魏明 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<