一、关于

Consul是HashiCorp公司开源的服务网格(service mesh)解决方案,包含服务发现、健康检查、配置中心、安全服务通信以及多数据中心等特性。官网简介地址:https://www.consul.io/docs/intro

Spring Cloud Consul为Spring Boot应用提供了Consul集成。通过一些简单的注释,可以快速集成Consul实现包括服务发现、分布式配置和控制总线的功能。

Spring Cloud Consul主要特性如下:

  • 服务发现:可以向Consul代理注册实例,客户端可以使用spring管理的bean发现实例
  • 支持Spring Cloud LoadBalance以及Ribbon客户端负载均衡器
  • 支持Zuul,一个通过Spring Cloud Netflix的动态路由器和过滤器
  • 分布式配置:使用Consul键/值存储
  • 控制总线:使用Consul事件的分布式控制事件

本文代码仓库地址:https://github.com/lazyrabb1t/rabb-springcloud-demo

二、使用Spring Cloud Consul实现服务发现以及配置中心

1、安装Consul

从官网下载Consul,这里我是用的是1.10.6版本的,下载地址:https://www.consul.io/downloads

下载完成后解压,然后在解压目录执行以下命令,以开发模式启动:

consul agent -dev 

启动成功后就可以浏览器访问其管理界面了,地址如下:

http://localhost:8500/

2、创建服务提供者模块

引入依赖(这里生产者只提供服务,所有之引入了服务发现的依赖):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

application.yml文件配置如下:

server:
  port: 19000
spring:
  application:
    name: rabb-consul-provider
  cloud:
    consul:
      host: 127.0.0.1
      port: 8500
      discovery:
        service-name: ${spring.application.name}

添加测试接口:

@SpringBootApplication
@RestController
@Slf4j
public class ConsulProviderApplication {

    @Value("${server.port}")
    String port;

    public static void main(String[] args) {
        SpringApplication.run(ConsulProviderApplication.class, args);
    }

    @GetMapping
    public String hello() {
        log.info("调用提供者hello接口");
        return "Hello SpringCloud! from port:" + port;
    }
}
3、创建消费者模块

引入依赖(消费者模块同时引入服务发现以及配置中心的依赖):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

bootstrap.yml配置如下:

server:
  port: 19001
spring:
  profiles:
    active: dev
  application:
    name: rabb-consul-consumer
  cloud:
    consul:
      host: 127.0.0.1
      port: 8500
      discovery:
        service-name: ${spring.application.name}
      config:
        # 开启配置中心功能,默认开启
#        enabled: true
        # 开启配置变更监控,默认开启
#        watch:
#          enabled: true
        # 按照以下配置,会从consul中读取键名为config/rabb-consul-consumer,dev/data的数据
        # 设置配置值的根文件夹
        prefixes: config
        # 配置文件夹名称
        default-context: ${spring.application.name}
        # 配置文件格式
        format: YAML
        # 环境的分隔符,默认英文逗号
#        profile-separator: '::'
        # 配置数据的key,默认data
        data-key: data
  main:
    allow-circular-references: true
service-url:
  provider: http://rabb-consul-provider`

注册RestTemplate,其中@LoadBalanced注解可以通过服务名称调用,并支持负载均衡:

@Configuration
public class RestConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public RestTemplate restTemplate2() {
        return new RestTemplate();
    }
}

添加测试接口,测试服务调用以及从配置中心读取配置,其中@RefreshScope注解可以动态的获取最新的配置,DiscoveryClient类可以帮助我们获取服务的信息:


@SpringBootApplication
@Slf4j
@RestController
@RefreshScope
public class ConsulConsumerApplication {

    @Autowired
    RestTemplate restTemplate;
    @Autowired
    RestTemplate restTemplate2;
    @Value("${service-url.provider}")
    String providerService;
    @Autowired
    DiscoveryClient discoveryClient;
    @Value("${name}")
    String url;

    public static void main(String[] args) {
        SpringApplication.run(ConsulConsumerApplication.class, args);
    }

    @GetMapping("ip")
    public String hello() {
        log.info("调用消费者hello接口");
        return "INVOKE PROVIDER HELLO METHOD:" + restTemplate2.getForEntity("http://127.0.0.1:19000", String.class).getBody();
    }

    @GetMapping("name")
    public String hello2() {
        log.info("调用消费者hello接口");
        return "INVOKE PROVIDER HELLO METHOD:" + restTemplate.getForEntity(providerService, String.class).getBody();
    }

    @GetMapping("services")
    public List<String> services() {
        return discoveryClient.getServices();
    }

    @GetMapping("url")
    public String config() {
        return url;
    }
}
4、配置中心添加数据

consul管理界面添加一条key为config/rabb-consul-consumer,dev/data的数据,值如下:

name: rabbit
5、测试

启动服务提供者以及消费者模块,调用消费者的各接口即可测试各功能。