安装 Consul

请查阅 installation documentation 说明如何安装 Consul.

Consul 代理

一个 Consul 代理客户端必须提供给所有的Spring Cloud Consul应用. 默认情况下, 代理客户端预设为 localhost:8500. 见 Agent documentation 关于如何启动代理客户端, 以及如何连接到 Consul 集群代理服务器. 对于开发, 你安装了 consul之后, 你可以使用下面的命令来启动 Consul代理 :

./src/main/bash/local_run_consul.sh

这将在服务模式下以8500端口启动代理, 可通过 http://localhost:8500 用户界面显示

关于 Consul 服务发现

服务发现是一个基于微服务架构的关键原则之一. 试图手动配置每个客户端或某种形式的约定是很难做的,并且也不稳定. Consul 通过 HTTP APIDNS 提供服务发现服务. Spring Cloud Consul 使用 HTTP API 进行服务注册和发现. 这并不妨碍 non-Sring Cloud 应用使用 DNS 接口. Consul 代理服务都运行在 cluster 环境下通过 gossip protocol 和使用 Raft consensus protocol 进行交互.

关于 Consul 注册

当客户端注册到 Consul, 它提供关于自身的元数据,如主机和端口, ID, 名称和标签等. 一个 HTTP Check 默认创建,Consul 每10秒的频率以 /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, 此客户端必须配置定位. 例如:

application.yml
spring:
  cloud:
    consul:
      host: localhost
      port: 8500
如果你使用 Spring Cloud Consul Config, 上述值将从application.yml 移植到 bootstrap.yml.

默认的服务名称, 实例ID和端口, 从Environment中分别以 ${spring.application.name}, Spring Context ID和${server.port}获取.

@EnableDiscoveryClient 标记应用程序既是一个 Consul "service" (即 自行注册) 也是一个 "client" (即 它能查询 Consul 其他服务列表到本地).

HTTP 健康检查

默认情况下使用"/health"路径来检查Consul实例的健康度,这是在Spring Boot Actuator应用程序端点默认的位置.在Actuator应用程序下 ,如果你使用非默认的上下文路径或servlet路径(例如 server.servletPath=/foo)或管理端点的路径(例如 management.contextPath=/admin)来改变这些. Consul检查终端健康度频率是可以配置的. "10s"和"1m"分别代表10秒和1分钟. Example:

application.yml
spring:
  cloud:
    consul:
      discovery:
        healthCheckPath: ${management.contextPath}/health
        healthCheckInterval: 15s

元数据和Consul标签

Consul不支持服务元数据. Spring Cloud的ServiceInstance有一个 Map<String, String> metadata领域. Spring Cloud Consul使用Consul标签功能接近元数据,直到Consul正式支持元数据. 构成key=value标签将分割后,分别对应Map 的键和值. 没有=符号的标签,将同时作为键和值.

application.yml
spring:
  cloud:
    consul:
      discovery:
        tags: foo=bar, baz

上述配置map集合为foo→barbaz→baz.

使Consul实例ID唯一

默认情况下注册consul实例ID是等于它的Spring Application Context ID.默认情况下,Spring Application Context ID是 ${spring.application.name}:逗号,分割,简介:${server.port}. 在大多数情况下,允许一个服务多个实例在一台机器上运行.如果必须进一步确定唯一性, 使用Spring Cloud,你可以通过在 spring.cloud.consul.discovery.instanceId设置一个唯一性标识来覆盖. 例如:

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

有了这元数据,多个服务实例将部署在本地主机上,这随机值使得实例唯一. Cloudfoundry的spring.application.instance_id将自动填充Spring Boot Actuator应用程序, 因此不需要随机值.

使用DiscoveryClient

Spring Cloud支持 Feign (REST客户端生成器) 和 Spring RestTemplate 使用逻辑服务名而不是物理 URLs访问.

不在特定的Netflix应用程序下,你也可以使用 org.springframework.cloud.client.discovery.DiscoveryClient的简单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;
}

关于Consul分布式配置

Consul提供 Key/Value Store存储配置和其他元数据. Spring Cloud Consul Config Config Server and Client是当仁不让的选择. 配置过程中特殊"bootstrap" 阶段加载到spring环境中. 默认情况下配置存储在/config文件下. 多个PropertySource实例是基于应用名字和使用配置文件模拟 Spring Cloud Config依次分解属性.例如,名称为"testApp"和用"dev"配置文件的应用程序将具有如下属性源创建:

config/testApp,dev/
config/testApp/
config/application,dev/
config/application/

明确的属性源位于上面, 不太明确的放在下面.所有的应用程序 config/application 目录下的属性都可以使用consul的配置. 在config/testApp属性只适合名为"testApp"服务实例.

应用程序启动正在读取配置. 发送HTTP POST`/refresh`请求将会导致配置重新加载.键值对存储 (Consul支持) 目前是不可能的,但在将来的项目中会添加.

如何激活

引入依赖org.springframework.cloud:spring-cloud-consul-config 将自动启动Spring Cloud Consul Config.

定制

Consul Config可以使用以下属性来定制:

bootstrap.yml
spring:
  cloud:
    consul:
      config:
        enabled: true
        prefix: configuration
        defaultContext: apps
        profileSeparator: '::'
  • enabled 设置为"false"将禁用Consul Config

  • prefix 设置配置文件公共路径

  • defaultContext 设置应用程序文件名

  • profileSeparator 配置文件属性设置分割符号

YAML或者Properties格式配置

使用YAML或者Properties格式非常方便的配置键值对.设置 spring.cloud.consul.config.format属性YAML或者PROPERTIES. 例如使用YAML:

bootstrap.yml
spring:
  cloud:
    consul:
      config:
        format: YAML

YAML必须在consul适当的data键设置.上述使用默认的键看起来像这样:

config/testApp,dev/data
config/testApp/data
config/application,dev/data
config/application/data

上述你可以在YAML文档存储一个列表的键.

你可以使用 spring.cloud.consul.config.data-key来更改数据键.

git2consul with Config

git2consul是Consul一个社区项目,从git仓库加载指定的key文件到Consul.默认键的名称就是文件名. YAML和Properties文件分别支持.yml.properties的扩展名. 设置spring.cloud.consul.config.format属性为FILES. 例如:

bootstrap.yml
spring:
  cloud:
    consul:
      config:
        format: FILES

给出下列的keys在/config目录下, development配置和foo应用程序名:

.gitignore
application.yml
bar.properties
foo-development.properties
foo-production.yml
foo.properties
master.ref

下列属性源文件将被创建:

config/foo-development.properties
config/foo.properties
config/application.yml

每个键值都需要一个正确格式在YAML或Properties文件里.

Fail Fast

如果consul配置不是有效的在某些情况下不失败是非常方便的(像在本地开发或某些测试情况下) . 在bootstrap.yml设置 spring.cloud.consul.config.failFast=false 原因是将使配置模块记录警告而不是抛出异常.这将允许应用程序继续正常启动.

Consul Retry

当你启动应用程序发现consul代理偶尔不能使用, 你可以要求它发生故障后重试. 你需要在类路径下添加 spring-retryspring-boot-starter-aop. 默认重试6次,初始间隔1秒,随后按指数1.1后续规避.你可以使用spring.cloud.consul.retry.*配置这些属性(和其他属性) . 在Spring Cloud Consul Config和Discovery registration着两项工作中配置.

充分利用重试机制添加一个RetryOperationsInterceptor 类型@Bean标注id为"consulRetryInterceptor" . Spring 提供RetryInterceptorBuilder很容易的实现重试.

Spring Cloud Bus with Consul

在后续的版本里介绍.

关于Hystrix断路器

在项目pom.xml文件引入spring-cloud-starter-hystrix的starter应用程序就可是使用Spring Cloud Netflix项目提供的Hystrix断路器. Hystrix并不依赖Netflix Discovery Client. @EnableHystrix应该放在配置类上 (通常是main类). 方法上注解@HystrixCommand来起到电路器的保护. 参阅 the documentation 了解更多详情.

Hystrix量度与Turbine和Consul整合

Turbine (由Spring Cloud Netflix项目提供)汇集多个实例的Hystrix metrics streams,因此仪表盘可以显示聚合视图. Turbine使用DiscoveryClient接口查询相关的的实例.使用Spring Cloud Consul的Turbine, Turbine配置的方式类似如下例子:

pom.xml
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-netflix-turbine</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>

请注意,Turbine依赖的不是starter.turbine starter引入是为了支持Netflix Eureka.

application.yml
spring.application.name: turbine
applications: consulhystrixclient
turbine:
  aggregator:
    clusterConfig: ${applications}
  appConfig: ${applications}

clusterConfigappConfig部分必须匹配,所以把服务ID用逗号分割成列表放到一个单独的配置属性是非常有用的.

Turbine.java
@EnableTurbine
@EnableDiscoveryClient
@SpringBootApplication
public class Turbine {
    public static void main(String[] args) {
        SpringApplication.run(DemoturbinecommonsApplication.class, args);
    }
}