搭建Consul服务
搭建单节点Consul
下载consul二进制文件:https://www.consul.io/downloads
使用如下命令启动consul:
nohup consul agent -server -data-dir=/usr/local/consul-data/ -node=agent-one -bind=0.0.0.0 -bootstrap-expect=1 -client=0.0.0.0 -ui > /usr/local/consul-data/logs/consul.lo
g 2>&1 &
单节点扩容为集群
nohup consul agent -bind=0.0.0.0 -client=0.0.0.0 -data-dir=/usr/local/consul-data -node=agent-four -join=172.16.111.130 > /usr/local/consul-data/logs/consul.log 2>&1 &
172.16.111.130 为单点服务的 IP 地址
搭建Consul集群
# 10.200.110.90启动consul
consul agent -server -bootstrap-expect=3 -data-dir=/tmp/consul -node=10.200.110.90 -bind=10.200.110.90 -client=0.0.0.0 -datacenter=shenzhen -ui
# 10.200.110.91启动consul
consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node 10.200.110.91 -bind=10.200.110.91 -client=0.0.0.0 -datacenter shenzhen -ui
# 10.200.110.93启动consul
consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node 10.200.110.93 -bind=10.200.110.93 -client=0.0.0.0 -datacenter shenzhen -ui
consul 命令参数
server
: 以server身份启动。默认是client
bootstrap-expect
:集群要求的最少server数量,当低于这个数量,集群即失效。
data-dir
:data存放的目录,更多信息请参阅consul数据同步机制
node
:节点id,集群中的每个node必须有一个唯一的名称。默认情况下,Consul使用机器的hostname
bind
:监听的ip地址。默认绑定0.0.0.0,可以不指定。表示Consul监听的地址,而且它必须能够被集群中的其他节点访问。Consul默认会监听第一个private IP,但最好还是提供一个。生产设备上的服务器通常有好几个网卡,所以指定一个不会出错
client
: 客户端的ip地址,0.0.0.0是指谁都可以访问(不加这个,下面的ui :8500无法访问)
-config-dir
指定配置文件夹,Consul会加载其中的所有文件
-datacenter
指定数据中心名称,默认是 dc1
Spring Cloud 使用Consul
使用 Consul 作为注册中心提供服务
添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
服务提供方的Spring Boot配置:
server:
port: 8501
spring:
application:
name: producer
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: producer
服务提供方的启动类:
@SpringBootApplication
@EnableDiscoveryClient
public class ConsulProducerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulProducerApplication.class, args);
}
}
消费Consul 服务
添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
消费服务:
@RestController
public class ServiceController {
@Autowired
private LoadBalancerClient loadBalancer;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
/**
* 获取名称为producer的服务
*/
@RequestMapping("/services")
public Object services() {
return discoveryClient.getInstances("producer");
}
/**
* 负载均衡(轮询)的方式选择一个名称为producer的服务
*/
@RequestMapping("/discover")
public Object discover() {
return loadBalancer.choose("producer").getUri().toString();
}
@GetMapping("/invoke/hello")
public String invokeHello() {
String uri = loadBalancer.choose("producer").getUri() + "/hello";
return restTemplate.getForObject(uri, String.class);
}
}
使用Consul作为配置中心
添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
在consul添加配置:
配置内容为:
目标服务的SpringBoot Yaml配置(注意是bootstrap.yaml):
server:
port: 8501
spring:
application:
name: producer
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: producer
config:
enabled: true #是否启用配置中心功能
format: yaml #设置配置值的格式
prefix: config #设置配置所在目录
profile-separator: ':' #设置配置的分隔符
data-key: data #配置key的名字,由于Consul是K/V存储,配置存储在对应K的V中
消费配置:
@RestController
@RefreshScope // 自动刷新配置
public class HelloController {
// 对应在consul配置中心中的key为
// 路径/服务名称/key
// 这里是
// /config/producer/data
// 如果需要不同的profile区分,那么则应该是
// /config/producer:dev/dta
@Value("${config.info}")
private String configInfo;
@RequestMapping("/hello")
public String hello() {
return "hello " + configInfo;
}
}
Consul 的基本原理
上图共有两个datacenter 数据中心,也就是两个Consul集群。两个数据中心之间通过Internet网络(WAN)与 Gossip协议在端口8302上进行数据交互与同步。
每个datacenter内部,也就是每个集群是由多个consul agent组件构成,根据特性又可以将其分为:
Server:参与共识仲裁(raft)、存储群集状态(日志存储)、处理查询、维护与周边(LAN/WAN)各节点关系
Client:负责通过该节点注册到consul的微服务的健康检查、将客户端注册请求以及查询转化为对server的RPC请求、维护与周边(LAN/WAN)各节点关系