什么是OpenFeign
Feign是NetFlix开发的声明式、模板化的HTTP客户端,Feign可以帮助我们更便捷的调用HTTP API,Feign支持多种注解,
例如Feign自带的注解或者JAX-RS注解等,OpenFeign是对Feign的加强版,使其支持Spring MVC注解,另外还整合了Nacos和Ribbon,从而使用Feign更加的方便,Feign主要的优势就在于可以做到调用远程服务时就像调用本地的服务一样的体验。
开发者完全感知不到是远程API,更感知不到这是一个HTTP请求,它就像Dubbo一样,consumer直接调用接口方法provider,而不需要通过常规的Http Client构造请求在解析返回数据,主要还是解决了开发者无需关心调用远程API或无需关心分布式环境开发
整合OpenFeign
引入依赖
1 | org.springframework.cloudspring-cloud-starter-openfeign |
然后在启动类上加上Feign的注解:@EnableFeignClients
加上后就可以开始调用其他服务的方法了,具体实现如下
@FeignClient注解中就是去指定我们所要调用的服务信息,里面两个参数意思我在代码中给大家提示了,紧接着我们就可以像正常的调用service层去调用此方法了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package com.fujii.order.feign; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; /** * @Author: Fujii * @description: */ /** * name:指定调用rest接口所对应的服务名 * path:指定调用rest接口所在的controller中的@RequestMapping */ @FeignClient (name = "stock-service" ,path = "/stock" ) public interface StockFeignService { @GetMapping (value = "/reduct" ) public String reduct(); } |
这里我也把示例给大家粘贴出来吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | package com.fujii.order.controller; import com.fujii.order.feign.StockFeignService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @Author: Fujii * @description: 订单服务 */ @RestController @RequestMapping (value = "/order" ) public class OrderController { @Autowired private StockFeignService stockFeignService; @GetMapping (value = "/add" ) public String add(){ System.out.println( "下单成功!" ); String reduct = stockFeignService.reduct(); return "下单成功!" +reduct; } } |
然后我们启动服务查看是否能正常访问,如下图访问正常,说明配置无误
下面我在与大家说一下OpenFeign的其他的一些特性
日志配置
通过源码可以看到日志等级分为4种
- NONE【性能最佳,适用于生产环境】不记录任何日志信息(默认级别)
- BASIC【适用于生产环境追踪问题】仅记录请求方法、URL、响应状态和执行时间
- HEADRS:记录BASIC的基础之上 在记录请求和响应的HEAD
- FULL:【适用于开发环境和测试环境问题定位】记录请求和响应的HEAD、body和元数据
配置方式有两种:
第一种:全局配置 使用@Configuration进行全局配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package com.fujii.order.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @Author: Fujii * @description: OpenFeign日志输出 */ @Configuration public class FeignConfig { @Bean public Logger.Level feignLogLevel(){ return Logger.Level.FULL; } } |
这里配置好后大家在设置一个日志级别为DEBUG级别,因为springboot默认的日志级别是info,而feign的debug日志就不会输出出来
1 2 3 | logging: level: com.fujii.order.feign: debug |
设置好后去调用API后可以看到我调用了两个服务为stock-service的和product-service的
上面这种是全局配置,那么想要设置成局部配置 也是很简单,只需要在上面的config配置类中将@configuration注解清除掉 然后在配置文件中局部配置即可
1 2 3 4 5 | feign: client: config: product-service: loggerLevel: BASIC |
重启可查看到是生效了
还有一种方式就是直接在feign service的调用服务中去调用配置类也是可以生效具体实现如下:
契约配置
契约配置主要是解决我们之前可能有些项目中使用到了feign 用的是feign的一些注解 但是我想在这基础之上升级为OpenFeign 又不去改变原来的代码 那么就可以使用契约配置来解决,实现方式也很简单,以下是设置成局部修改成feign
1 2 3 4 5 6 | feign: client: config: product-service: loggerLevel: BASIC contract: feign.Contract.Default #设置为默认的契约模式 |
全局的需在配置文件中添加如下代码
1 2 3 4 | @Bean public Contract feignContract(){ return new Contract.Default(); } |
超时时间配置
超时时间主要是给我们的服务设置一个时间限制 超过这个限制则返回请求重试或者连接超时,设置起来也简单,下面我来演示一下全局配置和局部配置
全局配置:
1 2 3 4 | @Bean public Request.Options options(){ return new Request.Options( 5000 , 10000 ); } |
局部配置:
1 2 3 4 5 6 7 8 9 10 | feign: client: config: product-service: loggerLevel: BASIC contract: feign.Contract.Default #设置为默认的契约模式 #连接超时时间:默认是2秒 connectionTimeout: 5000 #请求处理超时时间 默认是5秒 readTimeout: 3000 |
当超过限制之后,会报错异常
自定义拦截器
openfign有一个拦截器可以帮助我们拦截服务中的一些请求的某些操作 实现的示例我放入以下参考,大家可以根据实际需求来扩展拦截的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.fujii.order.interceptor; import feign.RequestInterceptor; import feign.RequestTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @Author: Fujii * @description: */ public class CustomFeignIntercptor implements RequestInterceptor { Logger logger = LoggerFactory.getLogger( this .getClass()); @Override public void apply(RequestTemplate requestTemplate) { requestTemplate.header( "name" , "fujii" ); requestTemplate.query( "id" , "1" ); requestTemplate.uri( "9" ); logger.info( "feign拦截器" ); } } |
在写完拦截器之后我们还需要配置一下
1 2 3 4 5 6 7 8 9 10 11 12 | feign: client: config: product-service: loggerLevel: BASIC contract: feign.Contract.Default #设置为默认的契约模式 #连接超时时间:默认是2秒 connectionTimeout: 5000 #请求处理超时时间 默认是5秒 readTimeout: 10000 requestInterceptors [ 0 ] : #feign拦截器 com.fujii.order.interceptor.CustomFeignIntercptor |
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持IT俱乐部。