0
点赞
收藏
分享

微信扫一扫

SpringCloud整合Consul和Openfeign实现远程调用

爱动漫建模 2022-03-14 阅读 40

概述

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 相关依赖。代码如下:

	  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
       <!--  把 Consul 作为注册中心,并实现对其的自动配置 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <!--  通过它提供健康检查的接口给 Consul -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
  • 引入 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<ServiceInstance> 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组件依赖。如下:

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

定义FeignClient接口

在服务消费者创建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调用逻辑,实现远程调用。

举报

相关推荐

0 条评论