SpringCloud-2.0-周阳(9. 负载均衡 - OpenFeign)学习笔记

上一篇 :8. 负载均衡 - Ribbon

文章目录

1. 概述

1. 是什么

Feign 也支持可插拔式的编码器和解码器。

Feign 和 Open Feign 本质差不多,只不过 Open Feign 是 SpringCloud 对 Feign 进行了封装,使其支持了 SpringMVC 标准注解和 HttpMessageConverters。

  • 更多用于消费者端,做服务调用

2. 能干嘛

Feign能于什么

  • Feign旨在使编写Java Http客户端变得更容易。

  • 前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用

  • 所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。

Feign集成了Ribbon

  • 利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。
  • 而与Ribbon不同的是,通过 Feign 只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用

3. Feign和OpenFeign两者区别

  • Feign
  • Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端
  • Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。
  • Feign的使用方式是:使用Feign的注解定义接口,调用这个接口 ,就可以调用服务注册中心的服务
  • OpenFeign
  • OpenFeign是 Spring Cloud 在 Feign 的基础上支持了 SpringMVC 的注解,如 @RequesMapping 等等。
  • OpenFeign 的 @FeignClient 可以解析 SpringMVC 的 @RequestMapping 注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

2. OpenFeign 基本使用

  1. 新建模块 : cloud-consumer-order-Feign-80

  2. 修改 POM

     <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
         <dependency>
            <groupId>com.demo.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <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.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
    
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
  3. 编写 YML

    server:
      port: 80
    
    eureka:
      client:
        register-with-eureka: false
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
    
  4. 编写主启动类

    @SpringBootApplication
    // Feign 客户端的注解
    @EnableFeignClients
    public class FeignMain80 {
        public static void main(String[] args) {
            SpringApplication.run(FeignMain80.class, args);
        }
    }
    
  5. 业务类

  • 编写业务逻辑接口,调用 Provider 的服务 : PaymentFeignService

    // 注册组件
    @Component
    // 标注这是一个 Feign 接口, Value 值表示 微服务名称
    @FeignClient(value = "CLOUD-PAYMENT-SERVICE")
    public interface PaymentFeignService {
    	// 这个访问路径一定要和 Provider 的 Controller 的一模一样,不然报错
        @GetMapping("/provider/getPaymentById/{id}")
        public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
    }
    

    SpringCloud-2.0-周阳(9. 负载均衡 - OpenFeign)学习笔记

  • 编写 Controller : OrderFeignController

    @Slf4j
    @RestController
    @RequestMapping("/consumer")
    public class OrderFeignController {
        @Autowired
        private PaymentFeignService feignService;
    
        @GetMapping("/getPaymentById/{id}")
        public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
            return feignService.getPaymentById(id);
        }
    }
    

3. 超时控制

1. 是什么

  • 默认Feign客户端只等待一秒钟
  • 如果服务端处理需要超过1秒钟,导致Feign客户端不想等待了,直接返回报错。
  • 为了避免这样的情况,有时候我们需要设置Feign客户端的超时控制。
  • yml文件中开启配置

2. 演示超时

  • 故意设置超时演示出错情况
  1. 修改 Provider - 8001 的 Controller

    故意写一个暂停的语句

    /** 用于测试超时设置 */
    @GetMapping(value = "/payment/feign/timeout")
    public String timeOut(){
        // 休眠 3 秒
        try { 
            TimeUnit.SECONDS.sleep(3); 
        }catch (Exception e) {
            e.printStackTrace();
        }
        return serverPort;
    }
    
  2. 修改 Consumer - Feign - 80 的 Service

    @GetMapping(value = "/payment/feign/timeout")
    public String paymentFeignTimeout();
    
  3. 修改 Consumer - Feign - 80 的 Controller

    @GetMapping(value = "/provider/payment/feign/timeout")
    public String paymentFeignTimeout(){
        return feignService.paymentFeignTimeout();
    }
    
  4. 启动项目测试

    先访问一下 Provider

    SpringCloud-2.0-周阳(9. 负载均衡 - OpenFeign)学习笔记
    访问 Consumer

    SpringCloud-2.0-周阳(9. 负载均衡 - OpenFeign)学习笔记
    提示超时

3. 配置超时控制

  • OpenFeign 的超时控制其实是由 Ribbon 实现的
  1. 配置 YML

    # 设置 Feign 客户端超时时间
    ribbon:
      # 以下单位都是 ms 毫秒
      # 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
      ReadTimeout:  5000
      # 指的是建立连接后从服务器读取到可用资源所用的时间
      ConnectTimeout: 5000
    
  2. 重启项目测试
    SpringCloud-2.0-周阳(9. 负载均衡 - OpenFeign)学习笔记

4. 日志打印功能

4.1 是什么

  • Feign 提供了日志打印功能
  • 我们可以通过配置来调整日志级别,从而了解Feign中 Http请求的细节
  • 说白了就是对 Feign 接口的调用情况进行监控和输出

4.2 日志级别

  • NONE : 默认的,不显示任何日志;

  • BASIC : 仅记录请求方法、URL、响应状态码及执行时间;

  • HEADERS : 除了BASIC中定义的信息之外,还有请求和响应的头信息;

  • FULL : 除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。

4.3 使用

  • 修改 cloud-consumer-order-Feign-80
  1. 建立 Config 包,配置日志 Bean

    @Configuration
    public class FeignConfig {
        @Bean
        Logger.Level feignLoggerLevel(){
            return Logger.Level.FULL;
        }
    }
    
  2. 配置 YML

    在 YML 中开启日志的 Feign 客户端

    logging:
      level:
        com.demo.springcloud.service.PaymentFeignService: debug
    
  3. 测试
    SpringCloud-2.0-周阳(9. 负载均衡 - OpenFeign)学习笔记

上一篇:Spring Cloud学习(五)OpenFeign服务接口调用


下一篇:5.使用openfeign调用远程服务