3. Spring Cloud Commons:Common Abstractions
服务发现,负载平衡和断路器等模式适用于所有 Spring Cloud clients 都可以使用的 common 抽象层,独立于 implementation(e.g. 发现通过 Eureka 或 Consul)。
3.1 @EnableDiscoveryClient
Commons 提供@EnableDiscoveryClient
annotation。这将通过META-INF/spring.factories
查找DiscoveryClient
接口的 implementations。 _ Discovery Client 的实现将在org.springframework.cloud.client.discovery.EnableDiscoveryClient
key 下为spring.factories
添加 configuration class。 DiscoveryClient
__mplementations 的示例:Spring Cloud Netflix Eureka,Spring Cloud Consul Discovery和Spring Cloud Zookeeper Discovery。
默认情况下,DiscoveryClient
的_i实现 auto-register 本地 Spring Boot 服务器与 remote 发现服务器。可以通过在@EnableDiscoveryClient
中设置autoRegister=false
来禁用此功能。
不再需要使用
@EnableDiscoveryClient
。只需在 classpath 上使用DiscoveryClient
implementation 就可以使 Spring Boot application 向服务发现服务器注册。
3.1.1 健康指标
Commons _创建一个 Spring Boot HealthIndicator
,DiscoveryClient
__mplement 可以通过实现DiscoveryHealthIndicator
来参与。要禁用复合HealthIndicator
set spring.cloud.discovery.client.composite-indicator.enabled=false
。基于DiscoveryClient
的泛型HealthIndicator
是 auto-configured(
3.2 ServiceRegistry
Commons _now 提供ServiceRegistry
接口,提供register(Registration)
和deregister(Registration)
等方法,允许您提供自定义注册服务。 Registration
是标记界面。
@Configuration
@EnableDiscoveryClient(autoRegister=false)
public class MyConfiguration {
private ServiceRegistry registry;
public MyConfiguration(ServiceRegistry registry) {
this.registry = registry;
}
// called via some external process, such as an event or a custom actuator endpoint
public void register() {
Registration registration = constructRegistration();
this.registry.register(registration);
}
}
每个ServiceRegistry
implementation 都有自己的Registry
implementation。
-
ZookeeperRegistration
与ZookeeperServiceRegistry
一起使用 -
EurekaRegistration
与EurekaServiceRegistry
一起使用 -
ConsulRegistration
与ConsulServiceRegistry
一起使用
如果您使用ServiceRegistry
接口,则需要为正在使用的ServiceRegistry
implementation 传递正确的Registry
implementation。
3.2.1 ServiceRegistry Auto-Registration
默认情况下,ServiceRegistry
implementation 将运行服务。要禁用该行为,有两种方法。您可以将@EnableDiscoveryClient(autoRegister=false)
设置为永久禁用 auto-registration。您还可以设置spring.cloud.service-registry.auto-registration.enabled=false
以通过 configuration 禁用该行为。
3.2.2 Service Registry Actuator 端点
Commons 提供/service-registry
actuator 端点。此端点依赖于 Spring Application Context 中的Registration
bean。通过 GET 调用/service-registry/instance-status
将_return Registration
的状态。使用String
正文对相同端点的 POST 会将当前Registration
的状态更改为新的 value。请参阅您正在使用的ServiceRegistry
implementation 的文档,其中包含用于更新状态的允许值以及为状态恢复的值。
3.3 Spring RestTemplate 作为负载均衡器 Client
RestTemplate
可以自动配置为使用 ribbon。要创建负载均衡RestTemplate
创建RestTemplate
@Bean
并使用@LoadBalanced
限定符。
不再通过 auto configuration 创建
RestTemplate
bean。它必须由单独的 applications 创建。
@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;
}
}
URI 需要使用虚拟 host name(即 service name,而不是 host name)。 Ribbon client 用于创建完整的物理地址。有关如何设置RestTemplate
的详细信息,请参阅RibbonAutoConfiguration。
3.3.1 重试失败的请求
可以将负载平衡RestTemplate
配置为重试失败的请求。默认情况下,此逻辑被禁用,您可以通过将Spring 重试添加到 application 的 classpath 来启用它。负载平衡RestTemplate
将支持与重试失败请求相关的一些 Ribbon configuration 值。如果您想在 class 路径上使用 Spring Retry 禁用重试逻辑,则可以设置spring.cloud.loadbalancer.retry.enabled=false
。您可以使用的 properties 是client.ribbon.MaxAutoRetries
,client.ribbon.MaxAutoRetriesNextServer
和client.ribbon.OkToRetryOnAllOperations
。有关 properties 的作用的说明,请参阅Ribbon 文档。
如果要在重试中实现BackOffPolicy
,则需要创建类型的 bean,并
@Configuration
public class MyConfiguration {
@Bean
LoadBalancedBackOffPolicyFactory backOffPolciyFactory() {
return new LoadBalancedBackOffPolicyFactory() {
@Override
public BackOffPolicy createBackOffPolicy(String service) {
return new ExponentialBackOffPolicy();
}
};
}
}
上面示例中的
client
应替换为 Ribbon client 的 name。
如果要在重试中添加一个或多个RetryListener
,则需要创建类型的 bean,并_返回要用于给定服务的RetryListener
array。
@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.4 多个 RestTemplate objects
如果你想要一个非负载均衡的RestTemplate
,那么创建一个RestTemplate
bean 并 inject 它正常。要在创建@Bean
时使用@LoadBalanced
限定符来访问负载均衡RestTemplate
。
请注意下面 example 中 plain
RestTemplate
声明上的@Primary
annotation,以消除不合格的@Autowired
注入的歧义。
@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.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.5 忽略网络接口
有时忽略某些命名的网络接口是有用的,因此可以从 Service Discovery 注册中排除它们(例如,在 Docker 容器中运行)。可以设置正则表达式列表,这将导致忽略所需的网络接口。以下 configuration 将忽略“docker0”接口和所有以“veth”开头的接口。
application.yml.
spring:
cloud:
inetutils:
ignoredInterfaces:
- docker0
- veth.*
您还可以使用正则表达式列表强制仅使用指定的网络地址:
bootstrap.yml.
spring:
cloud:
inetutils:
preferredNetworks:
- 192.168
- 10.0
您还可以强制仅使用站点本地地址。有关详细信息,请参阅Inet4Address.html.isSiteLocalAddress()什么是站点本地地址。
application.yml.
spring:
cloud:
inetutils:
useOnlySiteLocalInterfaces: true
3.6 HTTP Client Factories
Spring Cloud Commons _provides beans for creating Apache HTTP clients(ApacheHttpClientFactory
)以及 OK HTTP clients(OkHttpClientFactory
)。只有在 classpath 上有 OK HTTP jar 时才会创建OkHttpClientFactory
bean。另外,Spring Cloud Commons _provides beans 用于创建 clients 使用的连接_manage,ApacheHttpClientConnectionManagerFactory
用于 Apache HTTP client,OkHttpClientConnectionPoolFactory
用于 OK HTTP client。如果要自定义在下游项目中创建 HTTP clients 的方式,可以提供自己的 beans 实现。您还可以通过将spring.cloud.httpclientfactories.apache.enabled
或spring.cloud.httpclientfactories.ok.enabled
设置为false
来禁用这些 beans 的创建。