Consul

搭建Consul服务

搭建单节点Consul

  1. 下载consul二进制文件:https://www.consul.io/downloads

  2. 放置到path路径下

使用如下命令启动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无法访问)

  • ui: 可以访问UI界面

  • -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添加配置:

配置内容为:

config:
  info: "张三"

目标服务的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组件构成,根据特性又可以将其分为:

  1. Server:参与共识仲裁(raft)、存储群集状态(日志存储)、处理查询、维护与周边(LAN/WAN)各节点关系

  2. Client:负责通过该节点注册到consul的微服务的健康检查、将客户端注册请求以及查询转化为对server的RPC请求、维护与周边(LAN/WAN)各节点关系

最后更新于