什么是OpenFeign?
OpenFeign是SpringCloud在Feign的基础上支持了SpringMVC的注解,其实就是对Feign的封装。
tips:Feign是Netflix的第三大组件,已停更,基本也没人用了,SpringCloud对其进行了封装,也就是OpenFeign。以下所提到的Feign都是指OpenFeign。
Feign能干什么?Feign旨在使编写Java Http客户端变得容易。
前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以Feign在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义。 在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了使用Ribbon时,自己封装服务调用客户端的开发量。简单的讲Feign就是用来做服务之间调用的组件,注意是用于客户端(也就是消费方)。和上文提到的RestTemplate实现的功能是一样的。
Feign集成了Ribbon 上文利用Ribbon维护了Payment服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。一、使用OpenFeign实现服务调用
1. 为了不和Ribbon订单工程弄混,新建一个订单服务工程,工程名:cloud-consumer-fegin-order,pom文件添加feign依赖
org.springframework.cloud spring-cloud-starter-openfeign
2. 修改yml文件如下server: port: 80eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://eureka8761.com:8761/eureka,http://eureka8762.com:8762/eureka
3. 主启动类添加注解开启Feign功能@SpringBootApplication@EnableFeignClientspublic class OrderFeignApplication { public static void main(String[] args) { SpringApplication.run(OrderFeignApplication.class, args); }}
4. 新建一个service接口@Component@FeignClient(value = "CLOUD-PROVIDER-PAYMENT")public interface PaymentFeignService { @GetMapping("/payment/get/{id}") CommonResult getPaymentById(@PathVariable("id") Long id);}
5. 新建controller,内容如下@RestControllerpublic class OrderFeignController { @Resource private PaymentFeignService paymentFeignService; @GetMapping("/consumer/payment/get/{id}") public CommonResult getPaymentById(@PathVariable("id") Long id){ return paymentFeignService.getPaymentById(id); }}
6. 按顺序启动两个eureka及两个支付服务,最后启动本服务,在浏览器测试可以看到不仅成功调用了支付服务,且自带负载均衡的功能。
各类之间调用关系:
二、OpenFeign超时控制
OpenFeign服务调用有个机制,当调用时间超过指定范围,会报错,默认1秒,我们模拟一个超时的场景。1. 在支付服务8001controller添加一个方法,让他休眠3秒@GetMapping(value = "/payment/feign/timeout")public String paymentFeignTimeout(){ try { Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } return serverPort;}
2. 在feign接口添加新接口@GetMapping(value = "/payment/feign/timeout")String paymentFeignTimeout();
3. OrderFeignController添加方法@GetMapping(value = "/consumer/payment/feign/timeout")public String paymentFeignTimeout(){ // openfeign客户端,默认等待1秒 return paymentFeignService.paymentFeignTimeout();}
4. 启动两个注册中心,支付服务8001,以及feign客户端80,在浏览器访问5. 报错的原因就是feign客户端80在访问支付服务8001超过1秒后,feign主动抛异常,但是这样肯定是不行的,实际工作中接口响应超过1秒太正常了,所以这时候我们需要设置超时控制。
修改feign客户端80yml文件,添加如下配置,超时控制重点ribbon: ReadTimeout: 5000 #指的是建立连接所需要的时间 ConnectTimeout: 5000 #指的是建立连接后从服务器读取到可用资源所用的时间
这时候再去访问,就可以正常返回了三、OpenFeign日志增强
Fegin提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Http请求的细节。说白了就是对Feign接口的调用情况进行监控和输出。1. 日志级别NONE:默认的,不显示任何日志
BASIC:仅记录请求方法、URL、响应状态码及执行时间
HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息
FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据
2. 配置Feign的日志管理
添加一个FeignConfig类,内容如下,注意这里Logger导的包是feign下的,别导成Log4j的包。
import feign.Logger;@Configurationpublic class FeignConfig { @Bean Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; }}
yml文件添加如下配置
logging: level: # 日志以什么级别监控哪个接口 com.wangyg.springcloud.service.PaymentFeignService: debug
3. 重启Feign客户端80服务,浏览器请求8001支付服务,这时候查看80的控制台,就可以看到打印的feign接口详细调用信息。到这里,OpenFeign的基本知识就学完了
接下来进入下一篇:服务熔断器Hystrix
本项目已上传到gitee和github,地址在公众号窗口 我的->git 查看相关内容