OpenFeign简介

Feign是一个声明式的Web Service客户端,是一种声明式、模板化的HTTP客户端。而OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样。你不用再自己拼接url,拼接参数等等操作,一切都交给Feign去做。和Ribbin+RestTemplate的方式比起来,OpenFeign更加的方便和符合MVC架构的习惯,而且OpenFeign也集成来Ribbon。

OpenFeign的使用

使用示范

引入依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. </dependency>

编写OpenFeign的Service类

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
@RequestMapping("/payment")
public interface PaymentFeignService {

    @RequestMapping("/pay")
    CommonResult<String> pay(@RequestParam("name") String name);

}

必须标上“@FeignClient”注解,并指定调用的微服务为“CLOUD-PAYMENT-SERVICE”,这里的方法只需和“CLOUD-PAYMENT-SERVICE”服务中的Controller方法保持一致即可

注意: 即使方法中只有一个参数,“@RequestParam”注解依然需要标注参数名,也就是不能简单的使用“@RequestParam”,而要像“@RequestParam(“name”)”这样规范,因为OpenFeign对此检查非常的严格

编写OpenFeign的Controller类

@RestController
@RequestMapping("/feign")
public class FeignController {
    @Resource
    private PaymentFeignService paymentFeignService;

    @RequestMapping("/pay")
    CommonResult<String> pay(@RequestParam("name") String name) {
        return paymentFeignService.pay(name);
    }
}

这种controller调service的架构是Java程序员习惯的

测试

image.png
可用看到通过80的feign的controller调用payment服务成功了

OpenFeign超时控制

OpenFeign对于一次http请求的默认超时时间是1秒钟,但是由于有些服务是长链路的调用,耗时间比较长,可能会超过最大时间限制的1s,因此可用根据实际情况进行配置超时控制。由于OpenFeign已经集成了Ribbin,因此我们可用再配置文件中配置:

#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
  #指的是建立连接所用的时间,适用于网络状况正常的情况下, 两端连接所用的时间
  ReadTimeout: 5000
  #指的是建立连接后从服务器读取到可用资源所用的时间
  ConnectTimeout: 5000

OpenFeign日志增强

OpenFeign提供了日志打印功能,如果需要查看详细的调用信息,就可以开启日志增强功能,配置如下:

logging:
  level:
    # feign日志以 debug 级别监控 com.atguigu.springcloud.service.PaymentFeignService 接口
    com.atguigu.springcloud.service.PaymentFeignService: debug

除此之外还需要注入OpenFeign自带的日志类:

@Configuration
public class FeignConfig {
    /**
     * NONE,
     * BASIC,
     * HEADERS,
     * FULL;
     * <p>
     * 日志级别
     *
     * @return
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

注意: 这个Logger使用的是“feign.Logger”,而不是slf4j框架中的Logger