Spring Cloud Consul 实现服务注册/发现

前置条件:首先根据 搭建Consul集群 搭建好Consul集群。

1 注册服务

下面使用Spring Cloud Consul 实现服务注册/发现。

  • Spring Cloud 版本:Greenwich.SR5
  • Spring Boot 版本:2.1.12.RELEASE (不是越新越好,要和Spring Cloud版本对应)
  • Consul 版本:1.6.3

引入依赖

首先需要引入几个依赖:

<!-- spring cloud consul 相关依赖 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>

<!-- 健康检查相关依赖 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- 如果需要提供web服务,需要引入web相关依赖 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

注册服务

如果一个应用服务想要将自己注册到Consul中,可以被其他服务发现,那么只需要在启动类上面加上@EnableDiscoveryClient注解就可以了:

@SpringBootApplication
@EnableDiscoveryClient
public class Service1Application {

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

应用服务作为客户端向Consul注册自己,客户端会将主机、端口、id、名称和标签等元数据注册到Consul中。默认情况下,会创建一个HTTP检查,每10秒执行一次/health端点检查,如果健康检查失败,则服务实例被标记。

在配置文件中配置服务信息

需要将服务信息配置在application.yml文件中:

server:
  address: 169.254.186.87
  port: 8755
  servlet:
    context-path: /${spring.application.name}

spring:
  application:
    name: service1
  cloud:
    consul:
      host: 192.168.232.128
      port: 8900
      discovery:
        register: true
        hostname: ${server.address}
        service-name: ${spring.application.name}
        instance-id: ${spring.application.name}-1
        health-check-interval: 15s
        health-check-critical-timeout: 30s
        health-check-path: ${server.servlet.context-path}/actuator/health

spring.cloud.consul.hostspring.cloud.consul.port配置Consul服务的ipport

spring.cloud.consul.discovery下面的配置配置应用服务相关的元数据信息:

  • hostname配置服务所在的主机ip
  • service-name配置服务名。
  • instance-id配置实例id。
  • health-check-*是健康检查相关的配置。
  • 等等。

健康检查的坑!!!

启动服务,在ConsulUI界面里面发现服务已经注册上去了,但是健康检查一直报错。
需要注意以下几点:
(1)是否引入了spring-boot-starter-actuator依赖,没有这个包,健康检查不起作用。

<!-- 健康检查相关依赖 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

(2)注意Spring CloudSpring Boot版本要对应,不是越新的越好。这个坑,没太注意,导致应用一直启动不起来。

因为我使用的Spring CloudGreenwich.SR5版本,Spring Boot要使用2.1.12.RELEASE版本,如果是使用了2.2.4.RELEASE最新版本,会报很多启动的错误。

(3)如果配置文件中配置了应用上下文,那么要重写checkPath

因为默认的健康检查路径是/actuator/health,但是如果在应用中配置了server.servlet.context-path,就需要重写spring.cloud.consul.discovery.health-check-path,要加上上下文才行。

在这里插入图片描述

启动验证

启动应用服务service1,然后访问ConsulUI界面查看服务是否已经注册了。
在这里插入图片描述

2 发现服务

现在,服务service1已经注册到Consul中了。
下面创建一个consul-consumer项目,通过DiscoveryClient来获取service1服务信息。

引入依赖

<!-- spring cloud consul 相关依赖 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>

<!-- 如果需要提供web服务,需要引入web相关依赖 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

服务配置

设置新的端口号8756

server:
  address: 169.254.186.87
  port: 8756
  servlet:
    context-path: /${spring.application.name}

spring:
  application:
    name: consul-consumer
  cloud:
    consul:
      host: 192.168.232.128
      port: 8900
      discovery:
        hostname: ${server.address}
        service-name: ${spring.application.name}
        instance-id: ${spring.application.name}-1
        health-check-interval: 15s
        health-check-critical-timeout: 30s
        health-check-path: ${server.servlet.context-path}/actuator/health

作为消费者,不需要注册到Consul中(如果需要提供服务给其他服务使用,也可以进行注册)。因此,这里不使用@EnableDiscoveryClient注解:

@SpringBootApplication
public class ConsulConsumerApplication {

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

创建一个Controller,注入DiscoveryClient,使用它来获取service1的服务信息:

@RestController
public class AppController {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/getService1Info")
    public String getService1Info() throws JsonProcessingException {
        List<ServiceInstance> services =  discoveryClient.getInstances("service1");
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(services);
    }
}

启动验证

启动consul-commer服务,这就是一个简单的web服务,然后通过consul-consumer/getService1Info接口验证是否获取到了service1的服务信息:
在这里插入图片描述
从上图可以看出,获取到了service1的服务信息。

注意:这里不能过滤掉那些曾经注册到consul中但是现在没有启动的服务!!!

发布了178 篇原创文章 · 获赞 152 · 访问量 61万+

猜你喜欢

转载自blog.csdn.net/hbtj_1216/article/details/104210799