4. 与 Consul 一起发现服务
服务发现是基于微服务的架构的关键原则之一。尝试手动配置每个客户端或某种形式的约定可能非常困难,而且可能非常脆弱。Consul 通过 HTTP API 和 DNS 提供服务发现服务。Spring Cloud Consul 利用 HTTP API 进行服务注册和发现。这不会阻止非 Spring Cloud 应用程序利用 DNS 接口。Consul Agents 服务器运行在一个集群中,该集群通过八卦协议进行通信并使用 Raft 共识协议。
4.1. 如何激活
要激活 Consul Service Discovery,请使用带有组的Startersorg.springframework.cloud
和工件 IDspring-cloud-starter-consul-discovery
. 有关使用当前 Spring Cloud Release Train 设置构建系统的详细信息,请参阅 Spring Cloud 项目页面。
4.2. 向领事注册
当客户端向 Consul 注册时,它会提供有关自身的元数据,例如主机和端口、id、名称和标签。默认情况下,会创建一个 HTTP 检查,Consul 会点击/actuator/health
endpoint 每 10 秒一次。如果运行状况检查失败,则服务实例将标记为严重。
Consul 客户端示例:
@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: cloud: consul: host: localhost port: 8500
如果您使用 Spring Cloud Consul Config,并且您已将spring.cloud.bootstrap.enabled=true 或spring.config.use-legacy-processing=true 或使用spring-cloud-starter-bootstrap ,则需要将上述值放在bootstrap.yml 而不是application.yml . |
默认服务名称、实例 ID 和端口,取自Environment
是${spring.application.name}
、Spring 上下文 ID 和${server.port}
分别。
要禁用 Consul Discovery Client,您可以将spring.cloud.consul.discovery.enabled
自false
. Consul Discovery Client 也将在以下情况下被禁用spring.cloud.discovery.enabled
设置为false
.
要禁用服务注册,您可以将spring.cloud.consul.discovery.register
自false
.
4.2.1. 将管理注册为单独的服务
当管理服务器端口设置为与应用程序端口不同的值时,通过将management.server.port
物业、管理服务将注册为与应用程序服务不同的服务。 例如:
spring: application: name: myApp management: server: port: 4452
上述配置将注册以下 2 项服务:
-
申请服务:
ID: myApp Name: myApp
-
管理服务:
ID: myApp-management Name: myApp-management
管理服务将继承其instanceId
和serviceName
从应用程序服务。 例如:
spring: application: name: myApp management: server: port: 4452 spring: cloud: consul: discovery: instance-id: custom-service-id serviceName: myprefix-${spring.application.name}
上述配置将注册以下 2 项服务:
-
申请服务:
ID: custom-service-id Name: myprefix-myApp
-
管理服务:
ID: custom-service-id-management Name: myprefix-myApp-management
可以通过以下属性进行进一步自定义:
/** 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
4.2.2. HTTP 健康检查
Consul 实例的运行状况检查默认为“/actuator/health”,这是 Spring Boot Actuator 应用程序中运行状况端点的默认位置。如果您使用非默认上下文路径或 servlet 路径(例如server.servletPath=/foo
)或管理端点路径(例如management.server.servlet.context-path=/admin
).
也可以配置 Consul 用于检查健康端点的间隔。“10s”和“1m”分别表示 10 秒和 1 分钟。
此示例说明了上述内容(请参阅spring.cloud.consul.discovery.health-check-*
属性,以获取更多选项)。
spring: cloud: consul: discovery: healthCheckPath: ${management.server.servlet.context-path}/actuator/health healthCheckInterval: 15s
您可以通过将spring.cloud.consul.discovery.register-health-check=false
.
应用标题
标头可以应用于运行状况检查请求。例如,如果您尝试注册使用 Vault 后端的 Spring Cloud Config 服务器:
spring: cloud: consul: discovery: health-check-headers: X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722
根据 HTTP 标准,每个标头可以有多个值,在这种情况下,可以提供一个数组:
spring: cloud: consul: discovery: health-check-headers: X-Config-Token: - "6442e58b-d1ea-182e-cfa5-cf9cddef0722" - "Some other value"
4.2.3. 执行器健康指示器
如果服务实例是 Spring Boot Actuator 应用程序,则可能会为其提供以下 Actuator 运行状况指示器。
发现客户端健康指标
当 Consul Service Discovery 处于活动状态时,将配置 DiscoverClientHealthIndicator 并可供 Actuator 运行状况端点使用。有关配置选项,请参阅此处。
4.2.4. 元数据
Consul 支持服务的元数据。Spring Cloud 的ServiceInstance
有一个Map<String, String> metadata
字段,该字段从服务填充meta
田。要填充meta
字段设置值spring.cloud.consul.discovery.metadata
或spring.cloud.consul.discovery.management-metadata
性能。
spring: cloud: consul: discovery: metadata: myfield: myvalue anotherfield: anothervalue
上述配置将导致一个服务的元字段包含myfield→myvalue
和anotherfield→anothervalue
.
生成的元数据
领事自动注册将自动生成一些条目。
钥匙 | 值 |
---|---|
“组” |
属性 |
“安全” |
如果属性为 True |
属性 |
属性 |
旧版本的 Spring Cloud Consul 填充了ServiceInstance.getMetadata() 方法,通过解析spring.cloud.consul.discovery.tags 财产。这不再受支持,请迁移到使用spring.cloud.consul.discovery.metadata 地图。 |
4.2.5. 使 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: 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 应用程序中自动填充,因此不需要随机值。
4.3. 查找服务
4.3.1. 使用负载均衡器
Spring Cloud 支持 Feign(REST 客户端构建器),并且还支持SpringRestTemplate
用于使用逻辑服务名称/ID 而不是物理 URL 查找服务。Feign 和发现感知型 RestTemplate 都利用 Spring Cloud LoadBalancer 进行客户端负载平衡。
如果您想使用 RestTemplate 访问服务 STORES,只需声明:
@LoadBalanced @Bean public RestTemplate loadbalancedRestTemplate() { return new RestTemplate(); }
并像这样使用它(请注意我们如何使用 Consul 的 STORES 服务名称/ID 而不是完全限定的域名):
@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 Cloud 现在还提供对 Spring Cloud LoadBalancer 的支持。 |
4.3.2. 使用 DiscoveryClient
您还可以使用org.springframework.cloud.client.discovery.DiscoveryClient
它为发现客户端提供了一个简单的 API,该 API 不特定于 Netflix,例如
@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; }
4.4. 执政官目录手表
领事目录手表利用领事手表服务的能力。目录监视会进行阻塞 Consul HTTP API 调用,以确定是否有任何服务已更改。如果有新的服务数据,则会发布心跳事件。
更改调用配置监视的频率 更改spring.cloud.consul.config.discovery.catalog-services-watch-delay
.默认值为 1000,以毫秒为单位。延迟是上一个调用结束和下一个调用开始后的时间量。
禁用目录监视集spring.cloud.consul.discovery.catalogServicesWatch.enabled=false
.
手表使用弹簧TaskScheduler
安排给领事的电话。默认情况下,它是ThreadPoolTaskScheduler
使用poolSize
的 1.要更改TaskScheduler
,创建一个类型为TaskScheduler
命名为ConsulDiscoveryClientConfiguration.CATALOG_WATCH_TASK_SCHEDULER_NAME
不断。