该项目通过自动配置和绑定到 Spring 环境和其他 Spring 编程模型习惯用法,为 Spring Boot 应用程序提供 Consul 集成。通过一些简单的注释,您可以快速启用和配置应用程序内的常见模式,并使用基于 Consul 的组件构建大型分布式系统。提供的模式包括服务发现、控制总线和配置。智能路由和客户端负载均衡、断路器是通过与其他 Spring Cloud 项目集成来提供的。
快速开始
本快速入门逐步介绍如何使用 Spring Cloud Consul 进行服务发现和分布式配置。
首先,在您的计算机上运行 Consul Agent。然后您可以访问它并将其用作 Spring Cloud Consul 的服务注册表和配置源。
发现客户端使用情况
要在应用程序中使用这些功能,您可以将其构建为依赖于 spring-cloud-consul-core
的 Spring Boot 应用程序。添加依赖项最方便的方法是使用 Spring Boot 启动器: org.springframework.cloud:spring-cloud-starter-consul-discovery
。我们建议使用依赖管理和 spring-boot-starter-parent
。以下示例显示了典型的 Maven 配置:
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>{spring-boot-version}</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
现在您可以创建一个标准的 Spring Boot 应用程序,例如以下 HTTP 服务器:
@SpringBootApplication
@RestController
public class Application {
@GetMapping("/")
public String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
当此 HTTP 服务器运行时,它会连接到在默认本地 8500 端口运行的 Consul Agent。要修改启动行为,您可以使用 application.properties
更改 Consul Agent 的位置,如下例所示:
spring:
cloud:
consul:
host: localhost
port: 8500
注意:可能踩坑 SpringCloud 集成consul,消费者报I/O error on GET request for...
您现在可以使用 DiscoveryClient
、 @LoadBalanced RestTemplate
或 @LoadBalanced WebClient.Builder
从 Consul 检索服务和实例数据,如以下示例所示:
@Autowired
private DiscoveryClient discoveryClient;
public String serviceUrl() {
List<ServiceInstance> list = discoveryClient.getInstances("STORES");
if (list != null && list.size() > 0 ) {
return list.get(0).getUri().toString();
}
return null;
}
分布式配置使用
要在应用程序中使用这些功能,您可以将其构建为依赖于 spring-cloud-consul-core
和 spring-cloud-consul-config
的 Spring Boot 应用程序。添加依赖项最方便的方法是使用 Spring Boot 启动器: org.springframework.cloud:spring-cloud-starter-consul-config
。我们建议使用依赖管理和 spring-boot-starter-parent
。以下示例显示了典型的 Maven 配置:
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>{spring-boot-version}</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
现在您可以创建一个标准的 Spring Boot 应用程序,例如以下 HTTP 服务器:
@SpringBootApplication
@RestController
public class Application {
@GetMapping("/")
public String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
如果您使用 Spring Cloud Consul Config,则需要设置 spring.config.import
属性才能绑定到 Consul。
安装consul
参考官网:Install Consul
Consul Agent 客户端必须可用于所有 Spring Cloud Consul 应用程序。默认情况下,代理客户端预计位于 localhost:8500
。有关如何启动代理客户端以及如何连接到 Consul 代理服务器集群的详细信息,请参阅代理文档。根据上面的文档启动开发代理。
这将在端口 8500 上以服务器模式启动代理,用户界面位于 localhost:8500
windows上可以配置一个服务,对Consul数据进行持久化
在consul的安装目录下,新建一个mydata文件夹,文件夹名字无要求
新建一个.bat脚本文件
参考:
@echo.服务启动......
@echo off
@sc create Consul binpath= "D:\devSoft\consul_1.17.0_windows_386\consul.exe agent -server -ui -bind=127.0.0.1 -client=0.0.0.0 -bootstrap-expect 1 -data-dir D:\devSoft\consul_1.17.0_windows_386\mydata "
@net start Consul
@sc config Consul start= AUTO
@echo.Consul start is OK......success
@pause
后续consul的配置数据会保存进mydata文件夹,重启也不会丢失
使用 Consul 进行服务发现
服务发现是基于微服务的架构的关键原则之一。尝试手动配置每个客户端或某种形式的约定可能非常困难,而且可能非常脆弱。 Consul 通过 HTTP API 和 DNS 提供服务发现服务。 Spring Cloud Consul 利用 HTTP API 进行服务注册和发现。这不会阻止非 Spring Cloud 应用程序利用 DNS 接口。 Consul Agents 服务器运行在集群中,通过 gossip 协议进行通信并使用 Raft 共识协议。
如何激活
要激活 Consul 服务发现,请使用带有组 org.springframework.cloud
和工件 ID spring-cloud-starter-consul-discovery
的启动器。有关使用当前 Spring Cloud 发布系列设置构建系统的详细信息,请参阅 Spring Cloud 项目页面。
向Consul注册
当客户端向 Consul 注册时,它会提供有关自身的元数据,例如主机和端口、id、名称和标签。默认情况下,Consul 会每 10 秒创建一次 HTTP 检查来检查 /actuator/health
端点。如果健康检查失败,服务实例将被标记为危险的。
@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);
}
}
如果 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
。当 spring.cloud.discovery.enabled
设置为 false
时,Consul Discovery Client 也将被禁用。
要禁用服务注册,您可以将 spring.cloud.consul.discovery.register
设置为 false
。
将管理注册为单独的服务
当管理服务器端口设置为与应用程序端口不同的端口时,通过设置 management.server.port
属性,管理服务将注册为与应用程序服务不同的单独服务。例如:
application.yml 应用程序.yml
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
HTTP 健康检查
Consul 实例的健康检查默认位于“/actuator/health”,这是 Spring Boot Actuator 应用程序中健康端点的默认位置。即使对于 Actuator 应用程序,如果您使用非默认上下文路径或 servlet 路径(例如 server.servletPath=/foo
)或管理端点路径(例如 management.server.servlet.context-path=/admin
),您也需要更改此设置。
Consul 用于检查健康端点的时间间隔也可以配置。 “10s”和“1m”分别代表10秒和1分钟。
application.yml 应用程序.yml
spring:
cloud:
consul:
discovery:
healthCheckPath: ${management.server.servlet.context-path}/actuator/health
healthCheckInterval: 15s
您可以通过设置 spring.cloud.consul.discovery.register-health-check=false
完全禁用 HTTP 运行状况检查。
应用标头
标头可应用于健康检查请求。例如,如果您尝试注册使用 Vault Backend 的 Spring Cloud Config 服务器:
根据 HTTP 标准,每个标头可以有多个值,在这种情况下,可以提供一个数组:
spring:
cloud:
consul:
discovery:
health-check-headers:
X-Config-Token:
- "6442e58b-d1ea-182e-cfa5-cf9cddef0722"
- "Some other value"
TTL健康检查
可以使用 Consul TTL 检查代替默认配置的 HTTP 检查。主要区别在于应用程序向 Consul 代理发送心跳信号,而不是 Consul 代理向应用程序发送请求。
还可以配置应用程序发送 ping 的时间间隔。 “10s”和“1m”分别代表10秒和1分钟。默认值为 30 秒。
此示例说明了上述内容(有关更多选项,请参阅附录页面中的 spring.cloud.consul.discovery.heartbeat.*
属性)。
application.yml
spring:
cloud:
consul:
discovery:
heartbeat:
enabled: true
ttl: 10s
TTL申请状态
对于 Spring Boot Actuator 应用程序,状态是根据其可用的运行状况端点确定的。当运行状况端点不可用(禁用或不是 Spring Boot Actuator 应用程序)时,它假定应用程序运行状况良好。
查询健康端点时,默认使用根健康组。可以通过设置以下属性来使用不同的健康组:
spring:
cloud:
consul:
discovery:
heartbeat:
actuator-health-group: <your-custom-group-goes-here>
自定义 TTL 应用状态
如果你想配置自己的应用状态机制,只需实现 ApplicationStatusProvider
接口即可
MyCustomApplicationStatusProvider.java
@Bean
public class MyCustomApplicationStatusProvider implements ApplicationStatusProvider {
public CheckStatus currentStatus() {
return yourMethodToDetermineAppStatusGoesHere();
}
}
查找服务
使用负载均衡器
Spring Cloud 支持 Feign(REST 客户端构建器),还支持 Spring RestTemplate
使用逻辑服务名称/ids 而不是物理 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 服务所在的数据中心。
使用 Consul 进行分布式配置
Consul 提供了一个键/值存储来存储配置和其他元数据。 Spring Cloud Consul Config 是配置服务器和客户端的替代方案。配置在特殊的“引导”阶段加载到 Spring 环境中。默认情况下,配置存储在 /config
文件夹中。多个 PropertySource
实例是根据应用程序的名称和模仿 Spring Cloud Config 解析属性顺序的活动配置文件创建的。例如,名称为“testApp”且配置文件为“dev”的应用程序将创建以下属性源:
config/testApp,dev/
config/testApp/
config/application,dev/
config/application/
目前是以,分割的,可以更改
spring:
application:
name: cloud-payment-service
####Spring Cloud Consul for Service Discovery
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
config:
profile-separator: '-' # default value is ",",we update '-'
format: YAML
# config/cloud-payment-service/data
# /cloud-payment-service-dev/data
# /cloud-payment-service-prod/data
最具体的属性来源位于顶部,最不具体的属性来源位于底部。 config/application
文件夹中的属性适用于所有使用consul进行配置的应用程序。 config/testApp
文件夹中的属性仅适用于名为“testApp”的服务实例。
目前,配置是在应用程序启动时读取的。发送 HTTP POST 到 /refresh
将导致配置重新加载。 Config Watch 还将自动检测更改并重新加载应用程序上下文。
如何激活
要开始使用 Consul 配置,请使用带有组 org.springframework.cloud
和工件 ID spring-cloud-starter-consul-config
的启动器。有关使用当前 Spring Cloud 发布系列设置构建系统的详细信息,请参阅 Spring Cloud 项目页面。
配置数据导入
Spring Boot 2.4 引入了一种通过 spring.config.import
属性导入配置数据的新方法。现在这是从 Consul 获取配置的默认方式。
要选择连接到 Consul,请在 application.properties 中设置以下内容:
spring.config.import=optional:consul:
这将连接到默认位置“http://localhost:8500”的 Consul Agent。删除 optional:
前缀将导致 Consul Config 在无法连接到 Consul 时失败。要更改 Consul Config 的连接属性,请设置 spring.cloud.consul.host
和 spring.cloud.consul.port
或将主机/端口对添加到 spring.config.import
语句,例如 spring.config.import=optional:consul:myhost:8500
Consul Config 将尝试根据 spring.cloud.consul.config.name
(默认为 spring.application.name
属性的值)和 spring.cloud.consul.config.default-context
(默认为 < b3>)。如果您想指定上下文而不是使用计算的上下文,则可以将该信息添加到 spring.config.import
语句中。
定制
Consul Config 可以使用以下属性进行定制:
spring:
cloud:
consul:
config:
enabled: true
prefix: configuration
defaultContext: apps
profileSeparator: '::'
如果您设置了 spring.cloud.bootstrap.enabled=true
或 spring.config.use-legacy-processing=true
,或者包含 spring-cloud-starter-bootstrap
,那么上述值将需要放置在 bootstrap.yml
而不是application.yml
-
enabled
将此值设置为“false”会禁用 Consul Config -
prefix
设置配置值的基本文件夹 -
defaultContext
设置所有应用程序使用的文件夹名称 -
profileSeparator
设置用于分隔属性源中的配置文件名称和配置文件的分隔符的值
配置观察
Consul Config Watch 利用 consul 监视键前缀的能力。 Config Watch 进行阻塞 Consul HTTP API 调用,以确定当前应用程序的任何相关配置数据是否已更改。如果有新的配置数据,则会发布刷新事件。这相当于调用 /refresh
执行器端点。
要更改调用 Config Watch 的频率,请更改 spring.cloud.consul.config.watch.delay
。默认值为 1000,单位为毫秒。延迟是上一次调用结束和下一次调用开始之间的时间量。
禁用配置监视集 spring.cloud.consul.config.watch.enabled=false
。
Watch使用 Spring TaskScheduler
来安排对 consul 的调用。默认情况下,它是一个 ThreadPoolTaskScheduler
, poolSize
为 1。要更改 TaskScheduler
,请创建一个 TaskScheduler
类型的 bean,命名为 ConsulConfigAutoConfiguration.CONFIG_WATCH_TASK_SCHEDULER_NAME
常数。
YAML 或带有配置的属性
与单独的键/值对相比,以 YAML 或属性格式存储属性块可能更方便。将 spring.cloud.consul.config.format
属性设置为 YAML
或 PROPERTIES
。例如使用 YAML:
spring:
cloud:
consul:
config:
format: YAML
如果您设置了 spring.cloud.bootstrap.enabled=true
或 spring.config.use-legacy-processing=true
,或者包含 spring-cloud-starter-bootstrap
,那么上述值将需要放置在 bootstrap.yml
快速失败
在某些情况下(例如本地开发或某些测试场景),如果 consul 不可用于配置,则可能很方便不会失败。设置 spring.cloud.consul.config.fail-fast=false
将导致配置模块记录警告而不是抛出异常。这将允许应用程序继续正常启动。
如果您设置了 spring.cloud.bootstrap.enabled=true
或 spring.config.use-legacy-processing=true
,或者包含 spring-cloud-starter-bootstrap
,那么上述值将需要放置在 bootstrap.yml