简介
文章翻译整理自Spring Cloud Consul官方文档。
Spring Cloud Consul项目通过autoconfiguration绑定到Spring Environment和其它Spring的编程习惯,为Spring Boot应用程序提供了Consul集成。通过简单的配置了可以构建基于Consul的Spring Cloud应用。同时提供了服务注册、控制总线、配置的集成支持,提供智能路由、客户端负载均衡和断路器功能的整合支持。
使用Consul进行服务注册发现
Consul通过HTTP API和DNS方式提供服务发现接口,并且提供Consul Connect的Sidecar模式。Spring Cloud Consul利用其HTTP API进行服务注册与发现。Consul Agent server可集群运行,使用gossip协议和Raft协议进行通信。
如何使用
在pom中引入Spring Cloud Consul相关的内容,如下的注册发现和配置能力
1 2 3 4 5 6 7 8 | <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> |
服务注册
当使用Consul进行注册时,将提供有关其自身的元数据如ip、port、id、name和tags。默认情况下还会创建一个HTTP Check,Consul每10秒会命中一次/health端点,如果健康检查失败了,服务实例将被标记为Critical。
- 服务实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @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应用,此处不使用SpringCloud注解的原因是,注册发现已经可以默认使用SpringBoot注解了。
- 配置consul地址application.yml
1 2 3 4 5 6 7 | spring: cloud: consul: host: localhost port: 8500 application: name: provider |
即可启动服务即可完成正常的服务实例注册
- 注册管路端口
management功能的开启需要引入spring-boot-starter-actuator
1 2 3 4 | <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> |
在指定了management端口和服务端口不一样的情况下,management才会作为单独服务注册到注册中心。
如下指定了management端口与服务端口不一致
1 2 3 | management: server: port: 4452 |
management服务的名称和ID继承应用的服务名称后接management,即{spring.application.name}-management
- 健康检查
Consul默认检查的端点为/health端点,即Spring Boot Aatuator的默认健康检查端点。
Spring Boot Actuator要做的事为将health端点暴露出来可以被外界访问,如
1 2 3 4 5 | management: endpoints: web: exposure: include: "*" |
但采用非系统默认的servlet.path或者management.server.servlet.context-path后需要相应的更改consul的健康检查配置,例如
1 2 3 4 5 6 | spring: cloud: consul: discovery: healthCheckPath: ${management.server.servlet.context-path}/health healthCheckInterval: 15s |
- 设置consul的metadata
Spring Cloud的ServiceInstance接口中有Map形式的metadata,但是consul目前不支持相关的直接映射。Spring Cloud Consul使用consul的Tags作为metadata的近似映射。
可通过配置consul tags的值添加额外的metadata信息, foo=bar的将被拆分为key、value,无键值对的将同时作为key和value
1 2 3 4 5 | spring: cloud: consul: discovery: tags: foo=bar, baz |
服务发现
Spring Cloud Consul的服务发现有两种方式:通过整合的负载均衡机制、使用DiscoveryClient API
使用负载均衡机制
Spring Cloud支持Feign和RestTemplate使用逻辑服务名进行服务发现。Feigh和具备服务发现能力的RestTemplate均使用Ribbon进行负载均衡。可按照Spring Cloud的原生用法进行服务发现和负载均衡。
值得注意的是,如果Consul为集群部署且跨越多个DC,单单使用服务ID进行服务发现是不够的,还需要通过配置指定服务的DC,
1 2 3 4 5 | spring: cloud: consul: datacenters: STORES: dc-test |
STORES为服务名,后缀value为dc标识。
Spring Cloud Ribbon项目已经处于maintennace状态,官方建议设置spring.cloud.loadbalancer.ribbon.enabled=false,以启用官方研发的BlockingLoadBalancerClient代替RibbonLoadBalancerClient。
DiscoveryClient接口
也可以直接使用DiscoveryClient进行服务实例的发现,DiscoveryClient为Spring Cloud Commons关于服务发现的抽象,不依赖任何的框架如Netflix等。
1 2 3 4 5 6 7 8 9 10 | @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的服务目录Watch机制
Consul Catalog Watch机制利用Consul实现服务实例Watch机制。Catalog Watch进行阻塞的Consul Http api调用,以确定是否有任何服务发生更改,若有更改则发送Heartbeat Event。
默认两次Catalog Watch之间的间隔为1000ms,可以通过spring.cloud.consul.config.discovery.catalog-services-watch-delay配置进行更改。此配置指的是上一次调用结束和下一次调用开始间的时间间隔。也可以通过spring.cloud.consul.discovery.catalogServicesWatch.enabled=false禁用。
Catalog Watch机制使用Spring的TaskScheduler定时执行阻塞的HTTP API调用,默认的ThreadPoolTaskScheduler线程池大小为1。
更改TaskSheduler的实现,可以创建一个名为ConsulDiscoveryClientConfiguration.CATALOG_WATCH_TASK_SCHEDULER_NAME的TaskScheduler Bean。
未知内容
- Spring的TaskShceduler机制
- Spring Cloud Consul Catalog Watch机制发现服务变更后,发送Heartbeat Event之后被谁接受与处理流程
- management信息中貌似含有promethus等metrics信息,需要好好调研使用