OpenFeign详解

目录

Feign介绍

Feign架构

OpenFeign远程调用示例

1. 引入pom依赖

2. 启动类开启Feign注解

3. 定义Feign接口

4. 调用Feign

5. 定义Feign日志级别

6. 调接口验证

OpenFeign扩展

配置日志级别

日志级别

配置方式

配置超时时间

契约配置

客户端配置

默认方式

使用HttpClient5

使用OkHttp

自定义Client

Gzip压缩

编解码

拦截器


Feign介绍

feign是Netflix的一个远程调用组件, 可以实现调远程服务像调本地方法一样方便

SpringCloudOpenFeign是对Feign的增强, 能够支持mvc的注解

官网:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/

Feign架构

OpenFeign远程调用示例

1. 引入pom依赖

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>
    
        <!-- openfeign 远程调用 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2. 启动类开启Feign注解

@SpringBootApplication
@EnableFeignClients //扫描和注册feign客户端bean定义
public class MallUserApplication {

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

3. 定义Feign接口

@FeignClient(value = "mall-order",path = "/order")
public interface OrderFeignService {

    @RequestMapping("/findOrderByUserId/{userIdsxxx}")
    R findOrderByUserId(@PathVariable("userIdsxxx") Integer userId);
}

4. 调用Feign

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    OrderFeignService orderFeignService;

    @RequestMapping(value = "/findOrderByUserId/{id}")
    public R  findOrderByUserId(@PathVariable("id") Integer id) {
        //openFeign调用   远程调用
        R result = orderFeignService.findOrderByUserId(id);
        return result;
    }
}

5. 定义Feign日志级别

@Configuration
public class FeignConfig {
    /**
     * 日志级别
     * 通过源码可以看到日志等级有 4 种,分别是:
     * NONE:不输出日志。
     * BASIC:只输出请求方法的 URL 和响应的状态码以及接口执行的时间。
     * HEADERS:将 BASIC 信息和请求头信息输出。
     * FULL:输出完整的请求信息。
     */
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

6. 调接口验证

OpenFeign扩展

配置日志级别

日志级别

  • NONE【性能最佳,默认值】:不记录任何日志。
  • BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。
  • HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
  • FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。

配置方式

1. bean配置

全局生效

// 注意: 此处配置@Configuration注解就会全局生效,如果想指定Feign接口生效,就不能配置@Configuration
public class FeignConfig {

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

局部生效

public class FeignConfig {

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}
@FeignClient(value = "mall-order",path = "/order", configuration = FeignConfig.class)
public interface OrderFeignService {

    @RequestMapping("/findOrderByUserId/{userIdsxxx}")
    R findOrderByUserId(@PathVariable("userIdsxxx") Integer userId);
}

 2. 配置文件配置

在application.yml配置文件中配置Client 的日志级别为debug才能正常输出日志

spring:
  cloud:
    openfeign:   #openfeign的配置
      client:
        config:
          default: # 全局生效
            loggerLevel: BASIC
          mall-order:  # 对应微服务
            loggerLevel: FULL

配置超时时间

1. 配置文件配置

spring:
    cloud:
        openfeign:
            client:
                config:
                  #对应微服务
                  mall-order:  
                    # 连接超时时间
                    connectTimeout: 3000
                    # 请求处理超时时间
                    readTimeout: 5000

2. java Bean配置

通过 Options 可以配置连接超时时间和读取超时时间,Options 的第一个参数是连接的超时时间(ms);第二个是请求处理的超时时间(ms)

@Bean
public Request.Options options() {
    return new Request.Options(3000, 5000);
}

补充说明: Feign的底层用的是Ribbon或者LoadBalancer,但超时时间以Feign配置为准 

契约配置

        Spring Cloud 在 Feign 的基础上做了扩展,可以让 Feign 支持 Spring MVC 的注解来调用。原生的 Feign 是不支持 Spring MVC 注解的,如果你想在 Spring Cloud 中使用原生的注解方式来定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud 中默认SpringMvcContract

示例: 修改契约配置,支持Feign原生的注解(不再支持mvc注解)

1. java Bean配置

@Bean
public Contract feignContract() {
    return new Contract.Default();
}
@FeignClient(value = "mall-order",path = "/order")
public interface OrderFeignService {
    @RequestLine("GET /findOrderByUserId/{userId}")
    public R findOrderByUserId(@Param("userId") Integer userId);
}

 2. 配置文件配置

spring:
    cloud:
        openfeign:
            client:
                config:
                  mall-order:  #对应微服务
                    loggerLevel: FULL
                    contract: feign.Contract.Default   #指定Feign原生注解契约配置

客户端配置

        Feign 中默认使用 JDK 原生的 URLConnection 发送 HTTP 请求,没有连接池,建议使用别的组件来替换掉 URLConnection,比如 Apache HttpClient5,OkHttp

默认方式

feign.Client.Default#execute

    @Override
    public Response execute(Request request, Options options) throws IOException {
      HttpURLConnection connection = convertAndSend(request, options);
      return convertResponse(connection, request);
    }

使用HttpClient5

        <!-- Apache HttpClient5 -->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-hc5</artifactId>
        </dependency>

参考配置类源码

使用OkHttp

1. 引入依赖

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
</dependency>

2. 修改yml配置

spring:
  cloud:
    openfeign:
      okhttp:       #feign client使用 okhttp
        enabled: true

参考源码org.springframework.cloud.openfeign.FeignAutoConfiguration.OkHttpFeignConfiguration

自定义Client

比如参考okhttp源码, 自定义netty客户端

Gzip压缩

开启压缩能节省网络IO传输, 提升接口性能

1. 修改yml文件

spring:
  cloud:
    openfeign:
      compression:  # 配置 GZIP 来压缩数据
        request:
          enabled: true          
          mime-types: text/xml,application/xml,application/json  
          min-request-size: 1024  # 最小请求压缩阈值
        response:
          enabled: true

2. 验证

编解码

        Feign 中提供了自定义的编码解码器设置,同时也提供了多种编码器的实现,比如 Gson、Jaxb、Jackson。我们可以用不同的编码解码器来处理数据的传输。如果你想传输 XML 格式的数据,可以自定义 XML 编码解码器来实现,或者使用官方提供的 Jaxb。

例如: 配置jackson编解码

1. 引入依赖

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-jackson</artifactId>
</dependency>

2. 注入Bean或者yml配置

@Bean
public Decoder decoder() {
    return new JacksonDecoder();
}
@Bean
public Encoder encoder() {
    return new JacksonEncoder();
}
spring:
  cloud:
    openfeign:
      client:
        config:
          mall-order:  #对应微服务
            # 配置编解码器
            encoder: feign.jackson.JacksonEncoder 
            decoder: feign.jackson.JacksonDecoder

拦截器

每次 feign 发起http调用之前,会去执行拦截器中的逻辑

public interface RequestInterceptor {

  /**
   * Called for every request. Add data using methods on the supplied {@link RequestTemplate}.
   */
  void apply(RequestTemplate template);
}

使用场景

  • 统一添加 header 信息
  • 对 body 中的信息做修改或替换

示例: 请求头传递traceId

1. 定义自定义拦截器, 继承RequestInterceptor

@Slf4j
public class TraceRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        if(null != attributes){
            HttpServletRequest request = attributes.getRequest();
            String traceId = request.getHeader("traceId");
            log.info("从Request中解析请求头:{}",traceId);
            //设置token
            template.header("traceId",traceId);
        }
    }
}

2. Bean或者yml注入拦截器

    @Bean
    public TraceRequestInterceptor traceRequestInterceptor(){
        return new TraceRequestInterceptor();
    }
spring:
    cloud:
        openfeign:
            client:
                config:
                  mall-order:  #对应微服务
                    requestInterceptors:  #配置拦截器
                      - com.kk.mall.demo.interceptor.TraceRequestInterceptor

3. 验证

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值