对于最新的稳定版本,请使用 Spring Cloud Consul 4.3.0spring-doc.cadn.net.cn

与 Consul 一起发现服务

服务发现是基于微服务的架构的关键原则之一。尝试手动配置每个客户端或某种形式的约定可能非常困难,而且可能非常脆弱。Consul 通过 HTTP APIDNS 提供服务发现服务。Spring Cloud Consul 利用 HTTP API 进行服务注册和发现。这不会阻止非 Spring Cloud 应用程序利用 DNS 接口。Consul Agents 服务器运行在一个集群中,该集群通过八卦协议进行通信并使用 Raft 共识协议spring-doc.cadn.net.cn

如何激活

要激活 Consul Service Discovery,请使用带有组的Startersorg.springframework.cloud和工件 IDspring-cloud-starter-consul-discovery. 有关使用当前 Spring Cloud Release Train 设置构建系统的详细信息,请参阅 Spring Cloud 项目页面spring-doc.cadn.net.cn

向领事注册

当客户端向 Consul 注册时,它会提供有关自身的元数据,例如主机和端口、id、名称和标签。默认情况下,会创建一个 HTTP 检查,Consul 会点击/actuator/healthendpoint 每 10 秒一次。如果运行状况检查失败,则服务实例将标记为严重。spring-doc.cadn.net.cn

Consul 客户端示例:spring-doc.cadn.net.cn

@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello world";
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}

(即完全正常的 Spring Boot 应用程序)。如果 Consul 客户端位于localhost:8500,则需要配置才能找到客户端。 例:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      host: localhost
      port: 8500
如果您使用 Spring Cloud Consul Config,并且您已将spring.cloud.bootstrap.enabled=truespring.config.use-legacy-processing=true或使用spring-cloud-starter-bootstrap,则需要将上述值放在bootstrap.yml而不是application.yml.

默认服务名称、实例 ID 和端口,取自Environment${spring.application.name}、Spring 上下文 ID 和${server.port}分别。spring-doc.cadn.net.cn

要禁用 Consul Discovery Client,您可以将spring.cloud.consul.discovery.enabledfalse. Consul Discovery Client 也将在以下情况下被禁用spring.cloud.discovery.enabled设置为false.spring-doc.cadn.net.cn

要禁用服务注册,您可以将spring.cloud.consul.discovery.registerfalse.spring-doc.cadn.net.cn

将管理注册为单独的服务

当管理服务器端口设置为与应用程序端口不同的值时,通过将management.server.port物业、管理服务将注册为与应用程序服务不同的服务。 例如:spring-doc.cadn.net.cn

application.yml
spring:
  application:
    name: myApp
management:
  server:
    port: 4452

上述配置将注册以下 2 项服务:spring-doc.cadn.net.cn

ID: myApp
Name: myApp
ID: myApp-management
Name: myApp-management

管理服务将继承其instanceIdserviceName从应用程序服务。 例如:spring-doc.cadn.net.cn

application.yml
spring:
  application:
    name: myApp
management:
  server:
    port: 4452
spring:
  cloud:
    consul:
      discovery:
        instance-id: custom-service-id
        serviceName: myprefix-${spring.application.name}

上述配置将注册以下 2 项服务:spring-doc.cadn.net.cn

ID: custom-service-id
Name: myprefix-myApp
ID: custom-service-id-management
Name: myprefix-myApp-management

可以通过以下属性进行进一步自定义:spring-doc.cadn.net.cn

/** Port to register the management service under (defaults to management port) */
spring.cloud.consul.discovery.management-port

/** Suffix to use when registering management service (defaults to "management") */
spring.cloud.consul.discovery.management-suffix

/** Tags to use when registering management service (defaults to "management") */
spring.cloud.consul.discovery.management-tags

HTTP 健康检查

Consul 实例的运行状况检查默认为“/actuator/health”,这是 Spring Boot Actuator 应用程序中运行状况端点的默认位置。如果您使用非默认上下文路径或 servlet 路径(例如server.servletPath=/foo)或管理端点路径(例如management.server.servlet.context-path=/admin).spring-doc.cadn.net.cn

也可以配置 Consul 用于检查健康端点的间隔。“10s”和“1m”分别表示 10 秒和 1 分钟。spring-doc.cadn.net.cn

此示例说明了上述内容(请参阅spring.cloud.consul.discovery.health-check-*属性以获取更多选项)。spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      discovery:
        healthCheckPath: ${management.server.servlet.context-path}/actuator/health
        healthCheckInterval: 15s

您可以通过将spring.cloud.consul.discovery.register-health-check=false.spring-doc.cadn.net.cn

应用标题

标头可以应用于运行状况检查请求。例如,如果您尝试注册使用 Vault 后端Spring Cloud Config 服务器:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      discovery:
        health-check-headers:
          X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722

根据 HTTP 标准,每个标头可以有多个值,在这种情况下,可以提供一个数组:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      discovery:
        health-check-headers:
          X-Config-Token:
            - "6442e58b-d1ea-182e-cfa5-cf9cddef0722"
            - "Some other value"

TTL 运行状况检查

可以使用 Consul TTL 检查来代替默认配置的 HTTP 检查。主要区别在于应用程序向 Consul 代理发送心跳信号,而不是 Consul 代理向应用程序发送请求。spring-doc.cadn.net.cn

还可以配置应用程序用于发送 ping 的时间间隔。“10s”和“1m”分别表示 10 秒和 1 分钟。默认值为 30 秒。spring-doc.cadn.net.cn

此示例说明了上述内容(请参阅spring.cloud.consul.discovery.heartbeat.*属性以获取更多选项)。spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      discovery:
        heartbeat:
          enabled: true
          ttl: 10s

TTL 申请状态

对于 Spring Boot Actuator 应用程序,状态由其可用的运行状况终结点确定。当运行状况终结点不可用(禁用或不是 Spring Boot Actuator 应用程序)时,它假定应用程序处于良好运行状态。spring-doc.cadn.net.cn

查询运行状况终结点时,默认使用根运行状况组。通过设置以下属性,可以使用其他运行状况组:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      discovery:
        heartbeat:
          actuator-health-group: <your-custom-group-goes-here>

可以通过设置以下属性来完全禁用运行状况终结点的使用:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      discovery:
        heartbeat:
          use-actuator-health: false
自定义 TTL 应用程序状态

如果您想配置自己的应用程序状态机制,只需实现ApplicationStatusProvider接口spring-doc.cadn.net.cn

MyCustomApplicationStatusProvider.java
@Bean
public class MyCustomApplicationStatusProvider implements ApplicationStatusProvider {
	public CheckStatus currentStatus() {
        return yourMethodToDetermineAppStatusGoesHere();
    }
}

并将其提供给应用程序上下文:spring-doc.cadn.net.cn

@Bean
public CustomApplicationStatusProvider customAppStatusProvider() {
     return new MyCustomApplicationStatusProvider();
}

执行器健康指示器

如果服务实例是 Spring Boot Actuator 应用程序,则可能会为其提供以下 Actuator 运行状况指示器。spring-doc.cadn.net.cn

发现客户端健康指标

当 Consul Service Discovery 处于活动状态时,将配置 DiscoverClientHealthIndicator 并将其提供给 Actuator 运行状况端点。 有关配置选项,请参阅此处spring-doc.cadn.net.cn

领事健康指标

配置了一个指示器来验证ConsulClient.spring-doc.cadn.net.cn

默认情况下,它检索 Consul 领导者节点状态和所有注册服务。 在具有许多已注册服务的部署中,在每次运行状况检查中检索所有服务的成本可能很高。 跳过服务检索,仅检查领导者节点状态集spring.cloud.consul.health-indicator.include-services-query=false.spring-doc.cadn.net.cn

禁用指示器集management.health.consul.enabled=false.spring-doc.cadn.net.cn

当应用程序在引导上下文模式(默认)中运行时,此指示器将加载到引导上下文中,并且不可用于执行器运行状况终结点。

元数据

Consul 支持服务的元数据。Spring Cloud 的ServiceInstance有一个Map<String, String> metadata字段,该字段从服务填充meta田。 要填充meta字段设置值spring.cloud.consul.discovery.metadataspring.cloud.consul.discovery.management-metadata性能。spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      discovery:
        metadata:
          myfield: myvalue
          anotherfield: anothervalue

上述配置将导致一个服务的元字段包含myfield→myvalueanotherfield→anothervalue.spring-doc.cadn.net.cn

生成的元数据

领事自动注册将自动生成一些条目。spring-doc.cadn.net.cn

表 1.自动生成的元数据
钥匙

“组”spring-doc.cadn.net.cn

属性spring.cloud.consul.discovery.instance-group. 仅在以下情况下生成此值instance-group不是空的。spring-doc.cadn.net.cn

“安全”spring-doc.cadn.net.cn

如果属性为 Truespring.cloud.consul.discovery.scheme等于'https',否则为 false。spring-doc.cadn.net.cn

属性spring.cloud.consul.discovery.default-zone-metadata-name,默认为 'zone'spring-doc.cadn.net.cn

属性spring.cloud.consul.discovery.instance-zone. 仅在以下情况下生成此值instance-zone不是空的。spring-doc.cadn.net.cn

旧版本的 Spring Cloud Consul 填充了ServiceInstance.getMetadata()方法,通过解析spring.cloud.consul.discovery.tags财产。这不再受支持,请迁移到使用spring.cloud.consul.discovery.metadata地图。

使 Consul 实例 ID 唯一

默认情况下,consul实例注册的ID等于其Spring Application Context ID。默认情况下,Spring Application Context ID 为${spring.application.name}:comma,separated,profiles:${server.port}.在大多数情况下,这将允许一个服务的多个实例在一台计算机上运行。如果需要进一步的唯一性,使用 Spring Cloud,您可以通过在spring.cloud.consul.discovery.instanceId.例如:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    consul:
      discovery:
        instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

使用此元数据以及部署在 localhost 上的多个服务实例,随机值将在那里发挥作用,使实例唯一。在 Cloudfoundry 中,vcap.application.instance_id将在 Spring Boot 应用程序中自动填充,因此不需要随机值。spring-doc.cadn.net.cn

查找服务

使用负载均衡器

Spring Cloud 支持 Feign(REST 客户端构建器),并且还支持SpringRestTemplate用于使用逻辑服务名称/ID 而不是物理 URL 查找服务。Feign 和发现感知型 RestTemplate 都利用 Spring Cloud LoadBalancer 进行客户端负载平衡。spring-doc.cadn.net.cn

如果您想使用 RestTemplate 访问服务 STORES,只需声明:spring-doc.cadn.net.cn

@LoadBalanced
@Bean
public RestTemplate loadbalancedRestTemplate() {
     return new RestTemplate();
}

并像这样使用它(请注意我们如何使用 Consul 的 STORES 服务名称/ID 而不是完全限定的域名):spring-doc.cadn.net.cn

@Autowired
RestTemplate restTemplate;

public String getFirstProduct() {
   return this.restTemplate.getForObject("https://STORES/products/1", String.class);
}

如果您在多个数据中心有 Consul 集群,并且想要访问另一个数据中心的服务,则仅靠服务名称/ID 是不够的。在这种情况下 您使用属性spring.cloud.consul.discovery.datacenters.STORES=dc-west哪里STORES是服务名称/ID,并且dc-west是数据中心 STORES 服务所在的地方。spring-doc.cadn.net.cn

Spring Cloud 现在还提供对 Spring Cloud LoadBalancer 的支持。

使用 DiscoveryClient

您还可以使用org.springframework.cloud.client.discovery.DiscoveryClient它为发现客户端提供了一个简单的 API,该 API 不特定于 Netflix,例如spring-doc.cadn.net.cn

@Autowired
private DiscoveryClient discoveryClient;

public String serviceUrl() {
    List<ServiceInstance> list = discoveryClient.getInstances("STORES");
    if (list != null && list.size() > 0 ) {
        return list.get(0).getUri();
    }
    return null;
}

Consul 目录手表

Consul Catalog Watch 利用 consul 监视服务的能力。Catalog Watch 进行阻塞 Consul HTTP API 调用,以确定是否有任何服务已更改。如果有新的服务数据,则会发布检测信号事件。spring-doc.cadn.net.cn

更改调用配置监视的频率 更改spring.cloud.consul.config.discovery.catalog-services-watch-delay.默认值为 1000,以毫秒为单位。延迟是上一个调用结束和下一个调用开始后的时间量。spring-doc.cadn.net.cn

禁用目录监视集spring.cloud.consul.discovery.catalogServicesWatch.enabled=false.spring-doc.cadn.net.cn

手表使用弹簧TaskScheduler安排给领事的电话。默认情况下,它是ThreadPoolTaskScheduler使用poolSize的 1.要更改TaskScheduler,创建一个类型为TaskScheduler命名为ConsulDiscoveryClientConfiguration.CATALOG_WATCH_TASK_SCHEDULER_NAME不断。spring-doc.cadn.net.cn