通用抽象
Release Time 2024-04-10
3. Spring Cloud Commons:通用抽象
服务发现,负载平衡和断路器之类的模式将它们带到一个通用的抽象层,可以由所有Spring Cloud客户端使用,而与实现无关(例如,使用Eureka或Consul进行的发现) )。
3.1 @EnableDiscoveryClient
Spring Cloud Commons提供了@EnableDiscoveryClient
批注。这将寻找META-INF/spring.factories
与DiscoveryClient
接口的实现。Discovery Client的实现在org.springframework.cloud.client.discovery.EnableDiscoveryClient
键下将配置类添加到spring.factories
。DiscoveryClient
实现的示例包括Spring Cloud Netflix Eureka,Spring Cloud Consul发现和Spring Cloud Zookeeper发现。
默认情况下,DiscoveryClient
的实现会自动将本地Spring Boot服务器注册到远程发现服务器。可以通过在@EnableDiscoveryClient
中设置autoRegister=false
来禁用此行为。
不再需要@EnableDiscoveryClient
。您可以在类路径上放置DiscoveryClient
实现,以使Spring Boot应用程序向服务发现服务器注册。
3.1.1健康指标
公用创建了Spring Boot HealthIndicator
,DiscoveryClient
实现可以通过实现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
。否则,它可能会像已卷起的HealthIndicator
中的description
一样冒泡。
3.1.2订购DiscoveryClient
实例
DiscoveryClient
接口扩展了Ordered
。当使用多个发现客户端时,这很有用,因为它允许您定义返回的发现客户端的顺序,类似于如何订购由Spring应用程序加载的beans。默认情况下,任何DiscoveryClient
的顺序都设置为0
。如果要为自定义DiscoveryClient
实现设置不同的顺序,则只需覆盖getOrder()
方法,以便它返回适合您的设置的值。除此之外,您可以使用属性来设置Spring Cloud提供的DiscoveryClient
实现的顺序,其中包括ConsulDiscoveryClient
,EurekaDiscoveryClient
和ZookeeperDiscoveryClient
。为此,您只需要将spring.cloud.{clientIdentifier}.discovery.order
(对于Eureka,则为eureka.client.order
)属性设置为所需的值。
3.2服务注册
Commons现在提供一个ServiceRegistry
接口,该接口提供诸如register(Registration)
和deregister(Registration)
之类的方法,这些方法使您可以提供自定义的注册服务。Registration
是标记界面。
以下示例显示了正在使用的ServiceRegistry
:
@Configuration @EnableDiscoveryClient(autoRegister=false) public class MyConfiguration { private ServiceRegistry registry;
}
每个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自动注册Events
服务自动注册时将触发两个事件。注册服务之前会触发名为InstancePreRegisteredEvent
的第一个事件。注册服务后,将触发名为InstanceRegisteredEvent
的第二个事件。您可以注册ApplicationListener
,以收听和响应这些事件。
如果将
spring.cloud.service-registry.auto-registration.enabled
设置为false
,则不会触发这些事件。
3.2.2服务注册表执行器端点
Spring Cloud Commons提供了一个/service-registry
执行器端点。该端点依赖于Spring应用程序上下文中的Registration
bean。使用GET调用/service-registry
会返回Registration
的状态。对具有JSON正文的同一终结点使用POST会将当前Registration
的状态更改为新值。JSON正文必须包含带有首选值的status
字段。请参阅更新状态时用于允许值的ServiceRegistry
实现的文档以及为状态返回的值。例如,Eureka的受支持状态为UP
,DOWN
,OUT_OF_SERVICE
和UNKNOWN
。
3.3 Spring RestTemplate作为负载均衡器客户端
RestTemplate
可以自动配置为在后台使用负载均衡器客户端。要创建负载均衡的RestTemplate
,请创建RestTemplate
@Bean
并使用@LoadBalanced
限定符,如以下示例所示:
@Configuration public class MyConfiguration {
}
public class MyClass { @Autowired private RestTemplate restTemplate;
}
警告
RestTemplate
bean不再通过自动配置创建。各个应用程序必须创建它。
URI需要使用虚拟主机名(即服务名,而不是主机名)。Ribbon客户端用于创建完整的物理地址。有关如何设置RestTemplate
的详细信息,请参见RibbonAutoConfiguration。
重要
为了使用负载均衡的RestTemplate
,您需要在类路径中具有负载均衡器实现。推荐的实现是BlockingLoadBalancerClient
-添加org.springframework.cloud:spring-cloud-loadbalancer
以便使用它。RibbonLoadBalancerClient
也可以使用,但是目前正在维护中,我们不建议将其添加到新项目中。
如果要使用
BlockingLoadBalancerClient
,请确保项目类路径中没有RibbonLoadBalancerClient
,因为向后兼容的原因,默认情况下将使用它。
3.4 Spring WebClient作为负载均衡器客户端
WebClient
可以自动配置为使用负载均衡器客户端。要创建负载均衡的WebClient
,请创建WebClient.Builder
@Bean
并使用@LoadBalanced
限定符,如以下示例所示:
@Configuration public class MyConfiguration {
}
public class MyClass { @Autowired private WebClient.Builder webClientBuilder;
}
URI需要使用虚拟主机名(即服务名,而不是主机名)。Ribbon客户端用于创建完整的物理地址。
重要
如果要使用@LoadBalanced WebClient.Builder
,则需要在类路径中有一个loadbalancer实现。建议您将org.springframework.cloud:spring-cloud-loadbalancer
依赖项添加到项目中。然后,将在下面使用ReactiveLoadBalancer
。或者,此功能也可以在spring-cloud-starter-netflix-ribbon上使用,但是该请求将由后台的非响应LoadBalancerClient
处理。此外,spring-cloud-starter-netflix-ribbon已经处于维护模式,因此我们不建议您将其添加到新项目中。
在下面使用的ReactorLoadBalancer
支持缓存。如果检测到cacheManager
,将使用ServiceInstanceSupplier
的缓存版本。如果没有,我们将从发现服务中检索实例,而不进行缓存。如果您使用ReactiveLoadBalancer
,建议您在项目中启用缓存。
3.4.1重试失败的请求
可以配置负载均衡的RestTemplate
以重试失败的请求。默认情况下,禁用此逻辑。您可以通过在应用程序的类路径中添加Spring重试来启用它。负载平衡的RestTemplate
遵循与重试失败的请求有关的某些Ribbon配置值。您可以使用client.ribbon.MaxAutoRetries
,client.ribbon.MaxAutoRetriesNextServer
和client.ribbon.OkToRetryOnAllOperations
属性。如果要通过对类路径使用Spring重试来禁用重试逻辑,则可以设置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; }
}
3.5多个RestTemplate对象
如果您想要一个RestTemplate
而不是负载均衡的,请创建一个RestTemplate
bean并注入它。要访问负载均衡的RestTemplate
,请在创建@Bean
时使用@LoadBalanced
限定符,如以下示例所示:
@Configuration public class MyConfiguration {
}
public class MyClass { @Autowired private RestTemplate restTemplate;
}
重要
注意,在前面的示例中,在普通的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
。
3.6多个WebClient对象
如果要使WebClient
负载不均衡,请创建一个WebClient
bean并注入它。要访问负载均衡的WebClient
,请在创建@Bean
时使用@LoadBalanced
限定符,如以下示例所示:
@Configuration public class MyConfiguration {
}
public class MyClass { @Autowired private WebClient.Builder webClientBuilder;
}
3.7 Spring WebFlux WebClient作为负载均衡器客户端
3.7.1 Spring具有响应式负载均衡器的WebFlux WebClient
可以将WebClient
配置为使用ReactiveLoadBalancer
。如果将org.springframework.cloud:spring-cloud-loadbalancer
添加到项目中,并且spring-webflux
在类路径中,则会自动配置ReactorLoadBalancerExchangeFilterFunction
。以下示例说明如何配置WebClient
以在后台使用无功负载均衡器:
public class MyClass { @Autowired private ReactorLoadBalancerExchangeFilterFunction lbFunction;
}
URI需要使用虚拟主机名(即服务名,而不是主机名)。ReactorLoadBalancerClient
用于创建完整的物理地址。
3.7.2 Spring WebFlux WebClient,带有非反应式负载均衡器客户端
如果您的项目中没有org.springframework.cloud:spring-cloud-loadbalancer
,但是确实有spring-cloud-starter-netflix-ribbon,则仍可以将WebClient
与LoadBalancerClient
结合使用。如果spring-webflux
在类路径中,将自动配置LoadBalancerExchangeFilterFunction
。但是请注意,这是在后台使用非反应性客户端。以下示例显示如何配置WebClient
以使用负载均衡器:
public class MyClass { @Autowired private LoadBalancerExchangeFilterFunction lbFunction;
}
URI需要使用虚拟主机名(即服务名,而不是主机名)。LoadBalancerClient
用于创建完整的物理地址。
警告:现在不建议使用此方法。我们建议您将WebFlux与电抗性负载平衡器一起 使用。
3.7.3传递自己的Load-Balancer客户端配置
您还可以使用@LoadBalancerClient
批注传递您自己的负载平衡器客户端配置,并传递负载平衡器客户端的名称和配置类,如下所示:
@Configuration @LoadBalancerClient(value = “stores”, configuration = StoresLoadBalancerClientConfiguration.class) public class MyConfiguration {
}
也可以通过@LoadBalancerClients
注释将多个配置(对于一个以上的负载均衡器客户端)一起传递,如下所示:
@Configuration @LoadBalancerClients({@LoadBalancerClient(value = “stores”, configuration = StoresLoadBalancerClientConfiguration.class), @LoadBalancerClient(value = “customers”, configuration = CustomersLoadBalancerClientConfiguration.class)}) public class MyConfiguration {
}
3.8忽略网络接口
有时,忽略某些命名的网络接口很有用,以便可以将它们从服务发现注册中排除(例如,在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()。
Copyright © 2002 - 2024 VMware, Inc. All Rights Reserved.
Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.