Spring Cloud Commons:普通抽象

优质
小牛编辑
135浏览
2023-12-01

诸如服务发现,负载平衡和断路器之类的模式适用于所有Spring Cloud客户端可以独立于实现(例如通过Eureka或Consul发现)的消耗的共同抽象层。

@EnableDiscoveryClient

Commons提供@EnableDiscoveryClient注释。这通过META-INF/spring.factories查找DiscoveryClient接口的实现。Discovery Client的实现将在org.springframework.cloud.client.discovery.EnableDiscoveryClient键下的spring.factories中添加一个配置类。DiscoveryClient实现的示例是Spring Cloud Netflix EurekaSpring Cloud Consul发现Spring Cloud Zookeeper发现

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

ServiceRegistry

Commons现在提供了一个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实现都有自己的Registry实现。

服务部门自动注册

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

服务注册执行器端点

Commons提供/service-registry致动器端点。该端点依赖于Spring应用程序上下文中的Registration bean。通过GET调用/service-registry/instance-status将返回Registration的状态。具有String主体的同一端点的POST将将当前Registration的状态更改为新值。请参阅您正在使用的ServiceRegistry实现的文档,以获取更新状态的允许值和为状态获取的值。

Spring RestTemplate作为负载平衡器客户端

RestTemplate可以自动配置为使用功能区。要创建负载平衡RestTemplate创建RestTemplate @Bean并使用@LoadBalanced限定符。

警告通过自动配置不再创建RestTemplate bean。它必须由单个应用程序创建。
@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需要使用虚拟主机名(即服务名称,而不是主机名)。Ribbon客户端用于创建完整的物理地址。有关 如何设置RestTemplate的详细信息,请参阅 RibbonAutoConfiguration

重试失败的请求

负载平衡RestTemplate可以配置为重试失败的请求。默认情况下,该逻辑被禁用,您可以通过将Spring重试添加到应用程序的类路径来启用它。负载平衡RestTemplate将符合与重试失败请求相关的一些Ribbon配置值。如果要在类路径中使用Spring重试来禁用重试逻辑,则可以设置spring.cloud.loadbalancer.retry.enabled=false。您可以使用的属性是client.ribbon.MaxAutoRetriesclient.ribbon.MaxAutoRetriesNextServerclient.ribbon.OkToRetryOnAllOperations。请参阅Ribbon文档 ,了解属性的具体内容。

注意上述示例中的client应替换为您的Ribbon客户端名称。

多个RestTemplate对象

如果你想要一个没有负载平衡的RestTemplate,创建一个RestTemplate bean并注入它。要创建@Bean时,使用@LoadBalanced限定符来访问负载平衡RestTemplate

重要请注意下面示例中的普通RestTemplate声明的@Primary注释,以消除不合格的@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

忽略网络接口

有时,忽略某些命名网络接口是有用的,因此可以将其从服务发现注册中排除(例如,在Docker容器中运行)。可以设置正则表达式的列表,这将导致所需的网络接口被忽略。以下配置将忽略“docker0”接口和以“veth”开头的所有接口。

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

您还可以强制使用正则表达式列表中指定的网络地址:

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

您也可以强制仅使用站点本地地址。有关更多详细信息,请参阅Inet4Address.html.isSiteLocalAddress())是什么是站点本地地址。

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