Spring Cloud Consul
服务发现
这个项目主要是为了通过Spring Boot自动配置的机制整合Consul,并能够绑定到Spring Environment,以及其他Spring组件中。 通过一些简单的注解就可以在应用中快速的启用以及配置一个通用型Consul组件,并基于此来构建大型分布式系统。 这样就可以提供:服务发现,控制总线以及配置中心等功能。 智能路由(Zuul),客户端负载均衡(Ribbon)以及断路器(Hystrix)这些还是由Spring Cloud Netflix提供。
8.1 Install Consul 安装Consul
如何安装Consul,可以参见
8.2 Consul Agent 代理
Consul代理客户端一定要可以兼容所有的Spring Cloud Consul应用。 默认情况下,代理客户端会暴露在
localhost:8500
。 如何开启客户端以及如何连接到集群服务器可以参见 在安装完成后,就可以开始开发了,可以通过下列命令启动Consul代理:
./src/main/bash/local_run_consul.sh
这样就可以在8500端口开启一个代理服务器,可以通过
http://localhost:8500
访问。
8.3 Service Discovery with Consul 服务发现
服务发现是微服务架构的关键概念。手动为每一个客户端配置一些链接是非常非常的繁琐的。 Consul通过 和 来提供的服务发现功能。
Spring Cloud Consul利用HTTP API来进行服务注册和发现。但这并不妨碍非Spring Cloud应用从DNS来进行注册和发现。
Consul代理服务都是以方式运行的,内部通过和进行通讯。
8.3.1 How to activate
要开始使用Consul服务发现,先得加入相应的依赖:group:
org.springframework.cloud
artifact id :spring-cloud-starter-consul-discovery
。
8.3.2 Registering with Consul
当一个客户端注册到Consul,它会带上一些关于自身情况的元数据,如:主机地址、端口、id、名字以及一些额外标签。默认情况下Consul会每隔10秒,通过一个HTTP接口
/health
来节点的健康情况。 如果健康检测失败,那服务实例就会被标记成critical。
Consul客户端示例:
@SpringBootApplication@EnableDiscoveryClient@RestControllerpublic 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应用,没啥好说的。
如果默认的8500端口被占用,可以手工配置。例如:
application.yml
spring: cloud: consul: host: localhost port: 8500
警告: 如果使用了,那上面的值需要配置到bootstrap.yml
而不是application.yml
。
默认服务名、实例ID以及端口,都来自
Environment
中的${spring.application.name}
、Srping Context ID 以及${server.port}
。
@EnableDiscoveryClient
会让应用同时作为Consul的服务端和客户端,也即是:同时会注册自己也会在Consul查询别的服务。
8.3.3 HTTP Health Check
Consul实例会默认开启
/health
接口,对外提供健康检查。可以修改这个路径,无论是使用Actuator接口还是管理接口甚至使用非默认Context Path都行。 检查的间隔时间也可以配置。例如:
application.yml
spring: cloud: consul: discovery: healthCheckPath: ${management.contextPath}/health healthCheckInterval: 15s
Metadata and Consul tags
Consul 还不支持服务端元数据。Spring Cloud的
ServiceInstance
有一个Map<String, String> metadata
属性。Spring Cloud Consul可以使用Consul标签来模拟元数据。标签是以key=value
的形式,另取一个值作为key存放于Map
结构中。标签不能使用=
进行相等性判断,而是需要同时比较key和value。
application.yml
spring: cloud: consul: discovery: tags: foo=bar, baz
如上面的配置,map中将会存放:
foo→bar
和baz→baz
两个标签。
Making the Consul Instance ID Unique
默认情况下,Consul实例注册时会使用一个与Spring Application Context ID相同的ID。而默认的Spring Application Context ID是
${spring.application.name}:comma,separated,profiles:${server.port}
。所以,在大多数情况下,允许同一个服务的多个实例运行在同一个机器上。如果需要保证独立运行,可以使用Spring Cloud的spring.cloud.consul.discovery.instanceId
这个配置项,来替代默认值。例如:
application.yml
spring: cloud: consul: discovery: instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
通过这个元数据,本地的多个服务实例,会使用一个随机值来作为实例的唯一ID。在 Cloudfoundry环境中
vcap.application.instance_id
将会自动配置到Spring Boot应用中,因此,随机值也就不需要了。
8.3.4 Using the DiscoveryClient
Spring Cloud已经支持Feign,也支持Spring的
RestTemplate
通过一个逻辑服务名来替代物理URL。
可以使用
org.springframework.cloud.client.discovery.DiscoveryClient
来提供一个简单的API来为非Netflix应用提供服务发现接口。例如:
@Autowiredprivate DiscoveryClient discoveryClient;public String serviceUrl() { Listlist = discoveryClient.getInstances("STORES"); if (list != null && list.size() > 0 ) { return list.get(0).getUri(); } return null;}
8.4 Distributed Configuration with Consul
Consul提供了的方式来存放配置信息和其他元数据。 Spring Cloud Consul Config是一个用于替代的方案。 配置信息会在某个的"bootstrap"阶段,被加载到Spring Environment中。 配置信息默认存放在
/config
目录下。 基于应用名字以及Spring Cloud Config的配置文件方式来创建多个PropertySource
实例。 例如,一个应用名为:“testApp”,有一个“dev”的环境配置,那就会创建下列配置源:
- config/testApp,dev/
- config/testApp/
- config/application,dev/
- config/application/
越具体的配置源,越靠上,泛化适配的则靠下。
config/application
目录会被所有使用consul配置信息的应用所使用。config/testApp
目录仅会被服务为“testApp”的实例使用。
配置信息是可以在应用启动的时候读取到的。 发送一个HTTP POST请求到
/refresh
会自动重新加载配置信息。 目前版本还不支持对键值对进行监听(Consul支持),以后版本会加上这个特性。
8.4.1 How to activate
要想使用Consul配置信息,需要加上相应的starter:group :
org.springframework.cloud
artifact id :spring-cloud-starter-consul-config
。
这样Spring Cloud Consul Config就会自动配置。
8.4.2 Customizing
Consul Config可以按下列方式进行定制化配置:
bootstrap.yml
spring: cloud: consul: config: enabled: true prefix: configuration defaultContext: apps profileSeparator: '::'
- enabled 设置为“false”,则可以禁用Consul Config
- prefix 设置配置信息的root目录
- defaultContext 设置所有应用的配置信息目录
- profileSeparator 设置一个分隔符,用于配置源中的配置文件分隔
8.4.3 Config Watch
Consul Config Watch功能可以对某个key的配置信息进行。 当前应用的某个配置信息改动后,一个Refresh事件会被发布,并且Config Watch会触发阻塞式的HTTP接口调用来。 这等价于手动调用
/refresh
接口。
Config Watch延迟可以通过
spring.cloud.consul.config.watch.delay
进行修改。默认为1000,单位:毫秒。
可以设置
spring.cloud.consul.config.watch.enabled=false
禁用Config Watch。
8.4.4 YAML or Properties with Config
可以方便的使用YAML或者Properties格式来存放数据。 用
spring.cloud.consul.config.format
来指定YAML
或者PROPERTIES
。例如,使用YAML:
bootstrap.yml
spring: cloud: consul: config: format: YAML
这样在Consul中
data
的key就必须使用YAML。 就类似上例中那样:
- config/testApp,dev/data
- config/testApp/data
- config/application,dev/data
- config/application/data
任何一组键值都可以按YAML文档格式来存放。
可以通过
spring.cloud.consul.config.data-key
来改变data的key值。
8.4.5 git2consul with Config
git2consul是一个Consul社区中的项目,用于从git资源库中加载配置文件到Consul中。 默认情况下,使用文件名作为key值。 YAML和Properties分别对应着
.yml
以及.properties
后缀。 别忘了,设置spring.cloud.consul.config.format
为:FILES
。 例如:
bootstrap.yml
spring: cloud: consul: config: format: FILES
如果对于
/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文件。
8.4.6 Fail Fast
对于Consul配置信息可以方便的在不同的环境中转换(开发环境,测试环境),但是当配置信息不可用时会导致应用启动失败。 默认情况下,是一个Fail Fast机制。
不过,在
bootstrap.yml
中设置spring.cloud.consul.config.failFast=false
,这样会导致配置模块发出一个警告级别的日志,而不是抛出异常。这也将让应用能够正常启动。
8.5 Consul Retry
当应用启动时,如果想要兼容某个consul代理偶尔不可用状态,并想持续一段时间来确认。可以在classpath中引入:
spring-retry
和spring-boot-starter-aop
。这样在默认情况下,会重试6次,初始间隔1000毫秒,并每次按照1.1的指数进行时间补偿。
相关参数可以通过
spring.cloud.consul.retry.*
进行定制化配置。 这些对Spring Cloud Consul的Config和服务发现都起作用。
提示: 如果要完全控制重试,可以自定义一个id为"consulRetryInterceptor"的RetryOperationsInterceptor
并进行@Bean
注册。Spring还提供一个RetryInterceptorBuilder
来简化构建过程。
8.6 Spring Cloud Bus with Consul
8.6.1 How to activate
如果想要整合Consul Bus可以加入下列以来,group :
org.springframework.cloud
artifact id:spring-cloud-starter-consul-bus
。
8.7 Circuit Breaker with Hystrix
应用如果在pom.xml中加入了
spring-cloud-starter-hystrix
,就可以使用Spring Cloud Netflix的Hystrix断路器。 然而,Hystrix并没有依赖Netflix的服务发现机制。@EnableHystrix
可以加在配置类上。然后,带有@HystrixCommand
注解的方法就会当作断路器方法被调用。
8.8 Hystrix metrics aggregation with Turbine and Consul
Turbine(由Spring Cloud Netflix提供),汇集多个Hystrix实例的实时数据,并显示聚合视图。Turbine使用
DiscoveryClient
接口来查找相关实例。 当与Consul一起使用时,可以按下列方式进行配置:
pom.xml
org.springframework.cloud spring-cloud-netflix-turbine org.springframework.cloud spring-cloud-starter-consul-discovery
注意,Turbine依赖并不是一个starter。Turbine的starter在Netflix Eureka中才提供的。
application.yml
spring.application.name: turbineapplications: consulhystrixclientturbine: aggregator: clusterConfig: ${applications} appConfig: ${applications}
其中的
clusterConfig
和appConfig
,两者必须匹配,如果有多个值可以用逗号分割。
Turbine.java
@EnableTurbine@EnableDiscoveryClient@SpringBootApplicationpublic class Turbine { public static void main(String[] args) { SpringApplication.run(DemoturbinecommonsApplication.class, args); }}