前置条件:首先根据 搭建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.host
和spring.cloud.consul.port
配置Consul
服务的ip
和port
。
spring.cloud.consul.discovery
下面的配置配置应用服务相关的元数据信息:
hostname
配置服务所在的主机ip
。service-name
配置服务名。instance-id
配置实例id。health-check-*
是健康检查相关的配置。- 等等。
健康检查的坑!!!
启动服务,在Consul
的UI
界面里面发现服务已经注册上去了,但是健康检查一直报错。
需要注意以下几点:
(1)是否引入了spring-boot-starter-actuator
依赖,没有这个包,健康检查不起作用。
<!-- 健康检查相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
(2)注意Spring Cloud
和Spring Boot
版本要对应,不是越新的越好。这个坑,没太注意,导致应用一直启动不起来。
因为我使用的Spring Cloud
是Greenwich.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
,然后访问Consul
的UI
界面查看服务是否已经注册了。
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
中但是现在没有启动的服务!!!