OpenFeign 服务接口调用

OpenFeign是什么

Feign是一个声明式WebService客户端。使用Feign能让编写WebService客户端更加简单。

使用方法大致是定义一个服务接口然后再上面添加注解。Feign也支持可拔插式的编码器和解码器。SpringCloud对Feign进行了封装,使其支持了SpringMVC标准注解和HttpMessageConvertes。Feign可以与Eureka和Ribbon组合使用支持负载均衡。

Spring官网

GitHub

Feign的作用

Feign旨在使编写JavaHttp客户端变得更简单。使用RestTemplate利用RestTemplate对Htttp请求进行封装处理,形成了一套模板化的调用方法。但是实际开发中,往往一个接口会被多出调用,所以通常都会针对每个微服务自行封装一些客户端来包装这些服务的调用。因此Feign在此基础上做了进一步的封装,由Feign自身来帮助我们定义和实现依赖服务接口的定义。在Feign的帮助下,我们只需要创建一个接口并且使用注解的方式来配置它。即可完成对服务提供方的接口绑定,简化了使用RestTemplate时自行封装客户端的开发量。

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

Feign和OpenFeign的区别

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

使用OpenFeign实现服务之间的调用

调用端Controller示例

@RequestMapping("consumer")
@RestController
public class ConsumerController {
    /* 注入OpenFeign的客户端 */
    @Resource
    private ProviderClient providerClient;
    /**
    *  根据Id查询
    * @param id
    *        id
    * @return  {@link Result<Object>}
    * @author Error
    */
    @GetMapping("get/{id}")
    public Result<Object> get(@PathVariable(value = "id") Long id){
        return providerClient.getById(id);
    }
}

服务提供者Controller示例

@RequestMapping("provider")
@RestController
public class ProviderController {
    /* 注入服务提供者的Service */
    @Resource
    private ProviderService providerService;
    /**
    *  根据Id查询
    * @param id
    *        id
    * @return  {@link Result<Object>}
    * @author Error
    */
    @GetMapping("get/{id}")
    public Result<Object> get(@PathVariable(value = "id") Long id){
        return providerService.getById(id);
    }
}

Feign客户端接口示例

@FeignClient(value = "provider-service",path = "provider")
public interface ProviderClient {
    /**
     *  根据Id查询
     * @param id
     *        id
     * @return  {@link Result<Object>}
     * @author Error
     */
    @GetMapping("get/{id}")
    Result<Object> getById(@PathVariable(value = "id") Long id );
}

调用端直接调用FeignClient,FeignClient再通过服务名从注册中心获取到Provider的信息再去调用Provider。

超时控制

Feign客户端默认只会等待1s,再调用处理时间超过1s的服务,会直接报错。为了避免这样的情况可以再yml文件里面配置超时时间。

ribbon:
# ReadTimeout指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间。单位:ms
  ReadTimeout: 5000
# ConnectTimeout指的是建立后从服务器读取到可用资源所用的时间。单位:ms
  ConnectTimeout:5000

日志

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

日志级别

  1. NONE:默认的级别,不显示任何日志。
  2. BASIC:仅记录请求方法、URL、响应状态码以及执行时间。
  3. HEADERS:包括BASIC级别的所有信息,另外还有请求以及响应头的信息。
  4. FULL:包括HEADERS级别的所有信息,另外还有请求和响应的正文及其元数据。

配置OpenFeign日志级别

  1. 通过配置类配置:

    @Configuration
    public class OpenFeignConfig {
        /**
        *  配置OpenFeign的日志等级
        *  NONE:默认的级别,不显示任何日志。
        *  BASIC:仅记录请求方法、URL、响应状态码以及执行时间。
        *  HEADERS:包括BASIC级别的所有信息,另外还有请求以及响应头的信息。
        *  FULL:包括HEADERS级别的所有信息,另外还有请求和响应的正文及其元数据。
        * @return  {@link Logger.Level}
        * @author Error
        */
        @Bean
        public Logger.Level feignLoggerLevel(){
            return Logger.Level.FULL;
        }
    }
    
  2. 通过yml文件配置:

    feign:
      client:
        config:
          default:
            logger-level: FULL