服务发现与Consul
服务发现是基于微服务架构的关键原则之一。尝试配置每个客户端或某种形式的约定可能非常困难,可以非常脆弱。Consul通过HTTP API和DNS提供服务发现服务。Spring Cloud Consul利用HTTP API进行服务注册和发现。这不会阻止非Spring Cloud应用程序利用DNS界面。Consul代理服务器在通过八卦协议进行通信的集群中运行,并使用Raft协议协议。
如何激活
要激活Consul服务发现,请使用组org.springframework.cloud
和artifact id spring-cloud-starter-consul-discovery
的启动器。有关使用当前的Spring Cloud发布列表设置构建系统的详细信息,请参阅Spring Cloud项目页面。
注册Consul
当客户端注册Consul时,它提供有关自身的元数据,如主机和端口,ID,名称和标签。默认情况下会创建一个HTTP 检查,每隔10秒,Consul命中/health
端点。如果健康检查失败,则服务实例被标记为关键。
示例Consul客户端:
@SpringBootApplication
@EnableDiscoveryClient
@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,上述值将需要放在bootstrap.yml 而不是application.yml 中。 |
来自Environment
的默认服务名称,实例ID和端口分别为${spring.application.name}
,Spring上下文ID和${server.port}
。
@EnableDiscoveryClient
将应用程序设为Consul“服务”(即注册自己)和“客户端”(即可以查询Consul查找其他服务)。
HTTP健康检查
Consul实例的运行状况检查默认为“/ health”,这是Spring Boot执行器应用程序中有用端点的默认位置。如果您使用非默认上下文路径或servlet路径(例如server.servletPath=/foo
)或管理端点路径(例如management.context-path=/admin
),则需要更改这些,即使是执行器应用程序。也可以配置Consul用于检查运行状况端点的间隔。“10s”和“1m”分别表示10秒和1分钟。例:
spring: cloud: consul: discovery: healthCheckPath: ${management.context-path}/health healthCheckInterval: 15s
元数据和Consul标签
Consul尚未支持服务元数据。Spring Cloud的ServiceInstance
有一个Map<String, String> metadata
字段。Spring Cloud Consul使用Consul标签来近似元数据,直到Consul正式支持元数据。使用key=value
形式的标签将被分割并分别用作Map
键和值。标签没有相同的=
符号,将被用作键和值两者。
spring: cloud: consul: discovery: tags: foo=bar, baz
上述配置将导致具有foo→bar
和baz→baz
的映射。
使Consul实例ID唯一
默认情况下,一个领事实体注册了一个等于其Spring应用程序上下文ID的ID。默认情况下,Spring应用程序上下文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应用程序中自动填充,因此不需要随机值。
使用DiscoveryClient
Spring Cloud支持Feign(REST客户端构建器),Spring RestTemplate
使用逻辑服务名称而不是物理URL。
您还可以使用org.springframework.cloud.client.discovery.DiscoveryClient
,它为Netflix不特定的发现客户端提供了一个简单的API,例如
@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; }