Consul注册中心 #
一、Consul概述 #
1.1 什么是Consul #
Consul是HashiCorp公司开源的服务发现和配置管理工具,提供了完整的服务网格解决方案。
text
┌─────────────────────────────────────────────────────────────┐
│ Consul核心功能 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 服务发现 │ │ 健康检查 │ │ KV存储 │ │
│ │ Service │ │ Health │ │ Key-Value │ │
│ │ Discovery │ │ Checking │ │ Store │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 多数据中心 │ │ 服务网格 │ │ 安全通信 │ │
│ │ Multi │ │ Service │ │ Secure │ │
│ │ Datacenter │ │ Mesh │ │ Communication│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 Consul特性 #
| 特性 | 说明 |
|---|---|
| 服务发现 | 支持DNS和HTTP接口 |
| 健康检查 | 多种健康检查方式 |
| KV存储 | 分布式键值存储 |
| 多数据中心 | 支持多数据中心部署 |
| 服务网格 | 支持服务网格 |
| 安全通信 | TLS加密通信 |
1.3 Consul vs Nacos vs Eureka #
| 特性 | Consul | Nacos | Eureka |
|---|---|---|---|
| CAP | CP | AP/CP | AP |
| 一致性 | Raft | Distro/Raft | 弱一致 |
| 健康检查 | TCP/HTTP/gRPC | TCP/HTTP/MySQL | 心跳 |
| KV存储 | ✅ | ✅ | ❌ |
| 多数据中心 | ✅ | ❌ | ❌ |
| 配置中心 | ✅ | ✅ | ❌ |
二、安装部署 #
2.1 下载安装 #
bash
# macOS
brew install consul
# Linux
wget https://releases.hashicorp.com/consul/1.17.0/consul_1.17.0_linux_amd64.zip
unzip consul_1.17.0_linux_amd64.zip
sudo mv consul /usr/local/bin/
2.2 开发模式启动 #
bash
consul agent -dev
2.3 访问控制台 #
2.4 Docker部署 #
bash
docker run -d \
--name consul \
-p 8500:8500 \
-p 8600:8600/udp \
consul:1.17.0 agent -server -ui -bootstrap-expect=1 -client=0.0.0.0
三、服务注册发现 #
3.1 添加依赖 #
xml
<dependencies>
<!-- Spring Cloud Consul Discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
3.2 配置文件 #
yaml
spring:
application:
name: service-provider
cloud:
consul:
host: localhost
port: 8500
discovery:
enabled: true
register: true
service-name: ${spring.application.name}
instance-id: ${spring.application.name}:${server.port}
health-check-path: /actuator/health
health-check-interval: 10s
health-check-timeout: 5s
prefer-ip-address: true
ip-address: ${IP_ADDRESS:127.0.0.1}
port: ${server.port}
tags: version=1.0.0,author=team-a
server:
port: 8001
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
show-details: always
3.3 启动类 #
java
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
3.4 服务接口 #
java
@RestController
public class ProviderController {
@Value("${server.port}")
private String port;
@GetMapping("/hello")
public String hello() {
return "Hello from Consul Provider, port: " + port;
}
}
四、服务调用 #
4.1 使用RestTemplate #
java
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
java
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consume")
public String consume() {
return restTemplate.getForObject(
"http://service-provider/hello",
String.class
);
}
}
4.2 使用DiscoveryClient #
java
@RestController
public class DiscoveryController {
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/services")
public List<String> getServices() {
return discoveryClient.getServices();
}
@GetMapping("/instances/{serviceName}")
public List<ServiceInstance> getInstances(@PathVariable String serviceName) {
return discoveryClient.getInstances(serviceName);
}
}
五、健康检查 #
5.1 健康检查配置 #
yaml
spring:
cloud:
consul:
discovery:
health-check-path: /actuator/health
health-check-interval: 10s
health-check-timeout: 5s
health-check-critical-timeout: 30s
5.2 自定义健康检查 #
java
@RestController
public class HealthController {
@GetMapping("/health")
public Map<String, Object> health() {
Map<String, Object> health = new HashMap<>();
health.put("status", "UP");
health.put("timestamp", System.currentTimeMillis());
return health;
}
}
5.3 健康检查类型 #
| 类型 | 说明 |
|---|---|
| HTTP | HTTP请求检查 |
| TCP | TCP端口检查 |
| TTL | 时间间隔检查 |
| gRPC | gRPC服务检查 |
| Script | 脚本检查 |
六、集群部署 #
6.1 集群架构 #
text
┌─────────────────────────────────────────────────────────────┐
│ Consul集群架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Server │ │ Server │ │ Server │ │
│ │ (Leader) │ │ (Follower) │ │ (Follower) │ │
│ │ :8300 │ │ :8300 │ │ :8300 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ │ │ │ │
│ ┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐ │
│ │ Client │ │ Client │ │ Client │ │
│ │ Agent │ │ Agent │ │ Agent │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
6.2 Server配置 #
创建 server.json:
json
{
"datacenter": "dc1",
"data_dir": "/opt/consul/data",
"server": true,
"bootstrap_expect": 3,
"bind_addr": "0.0.0.0",
"client_addr": "0.0.0.0",
"ui": true,
"retry_join": ["consul-server1", "consul-server2", "consul-server3"]
}
6.3 启动Server #
bash
# Server 1
consul agent -config-dir=/etc/consul.d/server.json -node=server1
# Server 2
consul agent -config-dir=/etc/consul.d/server.json -node=server2
# Server 3
consul agent -config-dir=/etc/consul.d/server.json -node=server3
6.4 Client配置 #
创建 client.json:
json
{
"datacenter": "dc1",
"data_dir": "/opt/consul/data",
"server": false,
"bind_addr": "0.0.0.0",
"retry_join": ["consul-server1", "consul-server2", "consul-server3"]
}
6.5 Docker Compose部署 #
yaml
version: '3'
services:
consul-server1:
image: consul:1.17.0
container_name: consul-server1
command: agent -server -bootstrap-expect=3 -node=server1 -client=0.0.0.0 -ui
ports:
- "8500:8500"
networks:
- consul-net
consul-server2:
image: consul:1.17.0
container_name: consul-server2
command: agent -server -bootstrap-expect=3 -node=server2 -retry-join=consul-server1
networks:
- consul-net
consul-server3:
image: consul:1.17.0
container_name: consul-server3
command: agent -server -bootstrap-expect=3 -node=server3 -retry-join=consul-server1
networks:
- consul-net
networks:
consul-net:
driver: bridge
七、KV存储 #
7.1 使用KV存储 #
java
@RestController
public class KvController {
@Autowired
private ConsulClient consulClient;
@GetMapping("/kv/{key}")
public String getValue(@PathVariable String key) {
Response<GetValue> response = consulClient.getKVValue(key);
if (response.getValue() != null) {
return response.getValue().getDecodedValue();
}
return null;
}
@PutMapping("/kv/{key}")
public boolean setValue(@PathVariable String key, @RequestBody String value) {
consulClient.setKVValue(key, value);
return true;
}
@DeleteMapping("/kv/{key}")
public boolean deleteValue(@PathVariable String key) {
consulClient.deleteKVValue(key);
return true;
}
}
7.2 配置KV存储 #
yaml
spring:
cloud:
consul:
config:
enabled: true
prefix: config
default-context: application
profile-separator: ','
data-key: data
format: YAML
watch:
enabled: true
delay: 1000
八、配置详解 #
8.1 完整配置 #
yaml
spring:
application:
name: service-provider
cloud:
consul:
host: localhost
port: 8500
discovery:
enabled: true
register: true
deregister: true
service-name: ${spring.application.name}
instance-id: ${spring.application.name}:${server.port}
health-check-path: /actuator/health
health-check-interval: 10s
health-check-timeout: 5s
health-check-critical-timeout: 30s
health-check-tls-skip-verify: false
prefer-ip-address: true
ip-address: ${IP_ADDRESS:127.0.0.1}
port: ${server.port}
scheme: http
tags:
- version=1.0.0
- author=team-a
metadata:
version: 1.0.0
acl-token:
query-passing: true
catalog-services-watch-delay: 10s
catalog-services-watch-timeout: 5s
heartbeat:
enabled: false
ttl-value: 30
ttl-unit: s
interval-ratio: 2.0
config:
enabled: true
prefix: config
default-context: application
profile-separator: ','
data-key: data
format: YAML
watch:
enabled: true
delay: 1000
8.2 配置项说明 #
| 配置项 | 默认值 | 说明 |
|---|---|---|
| host | localhost | Consul服务器地址 |
| port | 8500 | Consul服务器端口 |
| enabled | true | 是否启用服务发现 |
| register | true | 是否注册服务 |
| service-name | $ | 服务名称 |
| health-check-interval | 10s | 健康检查间隔 |
| prefer-ip-address | false | 是否优先使用IP |
九、多数据中心 #
9.1 多数据中心架构 #
text
┌─────────────────────────────────────────────────────────────┐
│ 多数据中心架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 数据中心 DC1 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Server │ │ Server │ │ Server │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ WAN Gossip │
│ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 数据中心 DC2 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Server │ │ Server │ │ Server │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
9.2 配置多数据中心 #
json
{
"datacenter": "dc1",
"data_dir": "/opt/consul/data",
"server": true,
"bootstrap_expect": 3,
"bind_addr": "0.0.0.0",
"client_addr": "0.0.0.0",
"ui": true,
"retry_join": ["server1.dc1", "server2.dc1", "server3.dc1"],
"retry_join_wan": ["server1.dc2", "server2.dc2", "server3.dc2"]
}
十、最佳实践 #
10.1 生产环境配置 #
yaml
spring:
application:
name: service-provider
cloud:
consul:
host: ${CONSUL_HOST:localhost}
port: ${CONSUL_PORT:8500}
discovery:
enabled: true
register: true
service-name: ${spring.application.name}
instance-id: ${spring.application.name}:${server.port}
health-check-path: /actuator/health
health-check-interval: 10s
health-check-timeout: 5s
prefer-ip-address: true
ip-address: ${IP_ADDRESS:}
port: ${server.port}
tags:
- version=@project.version@
- region=${REGION:default}
acl-token: ${CONSUL_TOKEN:}
server:
port: ${PORT:8001}
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: when-authorized
10.2 注意事项 #
| 注意点 | 说明 |
|---|---|
| 集群节点 | Server至少3个 |
| 网络延迟 | 节点间延迟应小于50ms |
| 数据一致性 | CP系统,保证强一致性 |
| 健康检查 | 合理配置检查间隔 |
十一、总结 #
11.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 服务发现 | 支持DNS和HTTP接口 |
| 健康检查 | 多种检查方式 |
| KV存储 | 分布式配置存储 |
| 多数据中心 | 支持跨数据中心 |
| CP系统 | 保证强一致性 |
11.2 下一步 #
现在你已经掌握了Consul注册中心的使用,接下来让我们学习 服务调用,了解微服务间的通信方式!
最后更新:2026-03-28