Spring Cloud Consul 提供的 spring-cloud-consul-discovery 组件,基于 Spring Cloud 的编程模型,接入 Consul 作为注册中心,实现服务的注册与发现。
使用案例案例代码对象仓库:
服务提供者:consul-discovery-user-provider服务消费者:consul-discovery-user-consumer 项目搭建 Maven依赖
在 pom.xml 文件中,主要引入 Spring Cloud Consul Discovery 相关依赖。代码如下:
org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-consul-discovery org.springframework.boot spring-boot-starter-actuator
引入 spring-cloud-starter-consul-discovery 依赖,将 Consul 作为注册中心,并实现对它的自动配置。
引入 spring-boot-starter-actuator 依赖, 通过它提供健康检查的接口。
配置文件创建 application.yml配置文件,添加 Consul Discovery 配置项。配置如下:
server:
port: 8086
servlet:
context-path: /
spring:
# Spring Cloud Consul 通用配置项,{@link ConsulProperties}
cloud:
consul:
host: 172.24.29.120 #consul agent client 主机名字,默认是localhost
port: 8500
enabled: true #是否启用spring cloud consul,默认true
# Spring Cloud Consul Discovery 配置项,{@link ConsulDiscoveryProperties}
discovery:
register: true # 作为服务注册到Consul中,默认true
enabled: true # 是否启用服务发现,默认true
registerHealthCheck: true #是否启用服务健康检查,默认true
instance-id: ${spring.application.name}:${server.port}
prefer-ip-address: true
spring.cloud.consul 配置项,设置 Consul 客户端的配置,对应 ConsulProperties 配置类。spring.cloud.consul.discovery 配置项,设置 Consul Discovery 配置项,对应 ConsulDiscoveryProperties 配置类。 服务提供者
创建UserController类提供HTTP 接口,代码如下:
@RequestMapping("/user")
@RestController
public class UserController {
@RestController
static class TestController {
@GetMapping("/query")
public String echo(String name) {
return "provider:" + name;
}
}
}
创建 ConsulProviderApplication类,创建应用启动类。代码如下:
@EnableDiscoveryClient
@SpringBootApplication
public class ConsulProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulProviderApplication.class);
}
}
@EnableDiscoveryClient注解,开启Spring Cloud的服务发现功能。但是从 Spring Cloud Edgware 版本开始,已经不需要添加该注解,只需要引入服务发现组件,就会自动开启服务发现的功能。例如,我们这里已经引入了spring-cloud-starter-consul-discovery依赖,就不用再添加这个注解了。
服务消费者创建UserConsumerController类提供HTTP 接口,代码如下:
@Slf4j
@RequestMapping("/user")
@RestController
public class UserConsumerController {
@Autowired
DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
//用于调用服务提供者的 /user/query 接口
@GetMapping("/consumer2")
public String consumer2(String name) {
//通过服务发现组件获取服务实例
List instances = discoveryClient.getInstances("discovery-user-provider");
if(instances == null || instances.size() == 0){
throw new IllegalStateException("获取不到实例");
}
//通过服务实例 ServiceInstance 对象,拼接请求的目标 URL,使用 RestTemplate 发起 HTTP 调用。
String targetUrl = instances.get(0).getUri() + "user/query?name=" + name;
String response = restTemplate.getForObject(targetUrl, String.class);
return "consumer:" + response;
}
}
在 Spring Cloud Common 项目中,定义了 DiscoveryClient 接口,作为通用的服务发现客户端,提供查询服务列表的 API 方法。如果要集成到 Spring Cloud 体系的服务发现组件,需要提供对应的 DiscoveryClient 实现类。
Spring Cloud Alibaba Nacos Discovery 提供了 NacosDiscoveryClient 实现。Spring Cloud Consul Discovery 提供了 ConsulDiscoveryClient 实现。
如此,所有需要使用到的地方,只需要获取到 DiscoveryClient 客户端,而无需关注具体实现,保证其通用性。
创建 ConsulConsumerApplication类,创建应用启动类。代码如下:
@EnableFeignClients //@EnableDiscoveryClient 注解,已经无需添加,原因在上面已经解释过
@SpringBootApplication
public class ConsulConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulConsumerApplication.class);
}
//RestTemplate 是 Spring 提供的 HTTP 调用模板工具类,可以方便我们稍后调用服务提供者的 HTTP API。
@Configuration
public class RestTemplateConfiguration {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
}
测试
分别启动服务提供者和服务消费者,启动完成后,我们可以在 Consul 运维界面,看到该服务消费者。如下图所示:
注意:服务消费者和服务提供是一种角色的概念,本质都是一种服务,都是可以注册自己到注册中心的。
访问服务消费者接口如下:
curl http://127.0.0.1:8200/user/consumer2?name=unite
返回结果为 " consumer:provider:unite "。说明调用远程服务成功。
Openfeign实现远程调用 Maven依赖在服务消费者项目中pom.xml文件加入openfeign组件依赖。如下:
定义FeignClient接口org.springframework.cloud spring-cloud-starter-openfeign
在服务消费者创建UserFeignClient接口。代码如下:
//FeignClient注解设置服务提供者名字,在consul注册中心注册的服务名字
@FeignClient(name = "discovery-user-provider")
public interface UserFeignClient {
//定义服务提供者接口
@GetMapping("/user/query")
String echo(@RequestParam("name") String name);
}
服务消费者调用
在服务消费者应用中,UserConsumerController增加接口通过openFeign远程调用。代码如下:
@Slf4j
@RequestMapping("/user")
@RestController
public class UserConsumerController {
@Autowired
UserFeignClient userFeignClient;
@GetMapping("/consumer")
public String consumer(String name) {
String response = userFeignClient.echo(name);
return "consumer:" + response;
}
}
测试
访问服务消费者接口如下:
curl http://127.0.0.1:8200/user/consumer?name=unite
返回结果为 " consumer:provider:unite "。说明调用远程服务成功。
总结通过对比发现,两种方式都能实现远程调用。而OpenFeign封装复杂RPC调用逻辑,实现远程调用。



