Skip to content

OpenFeign

简介

OpenFeign 是一个声明式 Web 远程调用客户端。

OpenFeign 官方文档

依赖引入

可以在服务父模块统一引入依赖

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

开启功能

使用 @EnableFeignClients 注解开启功能

java
@EnableFeignClients //开启 Feign 远程调用
@EnableDiscoveryClient
@SpringBootApplication
public class OrderMainApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderMainApplication.class, args);
    }

}

远程调用

搭配 sentinel 可开启 fallback 兜底回调

java
@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class)
public interface ProductFeignClient {

    // feignClient 发送请求
    @GetMapping("/product/{id}")
    Product getProductById(@PathVariable("id") Long id);

}

日志管理

application.yml 进行日志配置

yaml
logging:
  level:
    cn.ttdgg.order.feign: debug

还需要在容器中注册一个 Logger.Level

java
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

超时配置

yaml
spring:
  cloud:
    openfeign:
      client:
        config:
          # 默认配置 
          default:
            logger-level: full
            connect-timeout: 1000
            read-timeout: 2000
          # 有精确设置优先精确设置  
          service-product:
            logger-level: full
            connect-timeout: 3000
            read-timeout: 5000

重试机制

默认是没有重试机制的,如果容器中有,则可以生效

java
@Bean
public Retryer retryer() {
    //默认重试间隔 100 ms ,每次 1.5 倍递增;最大间隔 1 s ; 最大重试次数 5 次
    return new Retryer.Default();
}

拦截器

示例:调用第三方发送短信接口,使用请求拦截器携带 Authorization 定义好调用第三方接口的 FeignClient

java
@FeignClient(value = "smsSent-client", url = "https://gyytz.market.alicloudapi.com")
public interface SmsFeignClient {

    @PostMapping("/sms/smsSend")
    String sendSms(
//                    @RequestHeader("Authorization") String authorization,
                    @RequestParam ("mobile") String mobile,
                   @RequestParam("templateId") String templateId,
                   @RequestParam("smsSignId") String smsSignId,
                   @RequestParam("param") String param
                   );
    
}

编写请求拦截器

java
/**
 * 为发送短信服务,提供一个请求拦截器,在请求头中添加 Authorization
 */
@Component
public class SmsRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        String appcode = "2b9b5e1b27e740729a21d9831d216dc5";
        String authorization = "APPCODE " + appcode;
        requestTemplate.header("Authorization", authorization);
    }

}

fallback - 兜底回调

  1. 引入 sentinel
xml
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  1. 开启熔断
yaml
feign:
  sentinel:
    enabled: true
  1. 编写 fallback 函数
java
@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class)
public interface ProductFeignClient {

    // feignClient 发送请求
    @GetMapping("/product/{id}")
    Product getProductById(@PathVariable("id") Long id);

}

@Component
public class ProductFeignClientFallback implements ProductFeignClient {

    @Override
    public Product getProductById(Long id) {
        System.out.println("兜底回调");
        Product product = new Product();
        product.setId(id);
        product.setPrice(new BigDecimal("0"));
        product.setProductName("未知商品");
        product.setNum(0);

        return product;
    }

}