1、什么是Feign
Feign是Netflix开发的声明式子,模板化的HTTP客户端,Feign可帮助我们更加便捷、优雅地调用HTTP API。
SpringCloud openfeign对Feign进行了增强,使其支持Spring MvC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便
优点:
Feign可以做到使用HTTP请求远程服务时就像调用本地方法一样的体验
,开发者完全感知不到这是远程方法,更感知不到这是一个HTTP请求。
2、SpringCloudAliBaba快速整合Feign
1、引入依赖
<!--添加openfeign的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2、编写调用接口
@FeignClient(value = "stock-server",path = "/stock") public interface StockFeignService { @RequestMapping("/stockList") public String getStock(); }
3、启动类上添加@EnableFeignClients注解
@EnableFeignClients @SpringBootApplication public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class,args); } }
4、发起调用,像调用本地方法一样调用远程服务
@RestController @RequestMapping("/order") public class OrderController { @Autowired StockFeignService stockFeignService; @GetMapping("/orderList") public String getOrder() { return stockFeignService.getStock(); } }
3、SpringCloud Feign的自定义配置及使用
3.1、日志配置
遇到Bug,如果接口调用失败,参数没收到等问题,就需要配置Feign的日志了,以便于将请求日志进行输出
1、定义一个配置类,指定日志级别
/** * 注意此处如果配置@Configuration注解就会全局生效,如果想指定对应微服务,就不能配置 */ public class FeignConfig { /** * 日志级别 **/ @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; } }
通过源码可以看到日志等级有四种,分别是
- NOHE【性能最佳,适用于生产】:不记录任何日志(默认值)
- BASIC【适用于生产环境追踪问题】:仅记录请求方法,URL、响应状态码以及执行时间。
- HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
- FULL:【比较适用于开发及测试环境定位问题】:记录请求和响应的header,body和元数据。
2、进行配置,让调用的微服务生效,在@FeignClient注解中指定使用的配置类
3、yml配置,由于springboot默认的日志级别是info,feign的debug日志级别不会输出
4、调用服务进行实验
先使用全局配置进行测试
编写好controller层
@RestController @RequestMapping("/order") public class OrderController { @Autowired StockFeignService stockFeignService; @Autowired ProductFeignService productFeignService; @GetMapping("/orderList") public String getOrder() { return stockFeignService.getStock()+productFeignService.getProduct(); } }
结果:
局部配置:对单一服务进行配置
步骤一:去掉FeignConfig
上面的@Configuration
注解
步骤二:在其中一个服务上添加配置
结果:
特别补充:当然,与Ribbon一样,Feign也可以在yml进行局部日志配置
#feign日志局部配置 feign: client: config: product-server: #对应微服务 logger-level: FULL
3.2、契约配置
Spring Cloud 在Feign的基础上做了扩展,使用Spring MVC的注解来完成Feign的功能,原生的Feign是不支持Spring MVC注解的,如果你想在SpringCloud中使用原生的注解方式定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud 中默认的是SpringMVCContract。
Spring Cloud 1早期版本就是用的原生Feign,随着netflix的停更换成了Open feign
1、修改契约配置,支持Feign原生的注解
@Bean public Contract feignContract(){ return new Contrat.Default(); }
2、OrderFeignService中配置使用Feign原生的注解
@FeignClient(value = "stock-server",path = "/stock") public interface StockFeignService { @RequestLine("GET /stockList") public String getStock(); }
3、补充,也可以通过yml配置契约
feign: client: config: product-server: #对应微服务 logger-level: FULL contract: feign.contract.Default #指定Feign原生注解契约配置
3.3、配置超时时间
通过Options可以配置连接超时时间和读取超时时间,Options的第一个参数是连接的超时时间(ms),默认值是2s;第二个请求处理的超时时间(ms),默认是5s
全局配置
@Bean public Request.Options options(){ return new Request.Options(5000,10000); }
yml中配置
feign: client: config: product-server: #对应微服务 # 连接超时时间(也可在配置类进行配置) connect-timeout: 5000 # 请求处理超时时间 read-timeout: 10000
3.4、自定义拦截器实现认证逻辑
在平常我们使用的拦截器,就是针对某个请求接口做出拦截,而这里的拦截器是针对服务与服务之见调用的拦截
1、自定义一个拦截器类
public class CustomerFeignInterceptor implements RequestInterceptor { Logger log = LoggerFactory.getLogger(this.getClass()); @Override public void apply(RequestTemplate requestTemplate) { // 业务逻辑 log.info("进入了拦截器"); String token = UUID.randomUUID().toString(); requestTemplate.header("Authorization",token); } }
2、全局配置
@Bean public CustomerFeignInterceptor customerFeignInterceptor() { return new CustomerFeignInterceptor(); }
3、yml方式配置(针对某一个服务做拦截)
feign: client: config: product-server: #对应微服务 request-interceptors: - com.lili.cloud.interceptor.feign.CustomerFeignInterceptor