一、概述
Feign是一个声明式的Web服务客户端,让编写Web服务客户端变得非常容易,只需创建一个借口并在接口上添加注解即可。
Github:https://github.com/spring-cloud/spring-cloud-openfeign
二、Feign 能干什么
Feign 旨在使编写 Java HTTP 客户端变得更加容易。
在使用 Ribbon + RestTemplate 时, 利用 RestTemplate 请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,对于服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常会针对每个微服务自行封装一些客户端类来包装这些服务依赖的调用。 所以,Feign 在此基础上除了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign 的实现下,我们只需要创建一个可口,并使用注解的方式来配置它(以前是Dao 接口上main标注 Mapper 注解,现在是一个微服务接口上面标注一个Feign 注解即可),即可完成对一个服务提供方的接口绑定,简化了使用 Spring cloud Ribbon 时, 自动封装服务调用客户端的开发量。
三、Feign 集成了 Ribbon
利用 Ribbon 维护了服务方的服务列表信息,并且通过伦序实现了客户杜u安的负载均衡,而 Ribbon 不同的是,通过feign 只需要定义服务绑定接口且一声明式的方法,优雅而简单的实现了服务调用。
四、Feign和OpenFeign的区别
4.1Feign
Feign 是 spring cloud 组件中的一个轻量级 RESTful 的HTTP 服务客户端 Reign 内置了 Ribbon, 用来做客户端服务在均衡,去调用服务注册中心的服务,Feign 的使用方式是:使用Feign 注解自定义接口,调用这个接口,就可以低哦啊用服务注册中心的服务。
4.2依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
4.3OpenFeign
openfeign 是 spring cloud 在 feign 的基础上支持 spring mvc 注解 ,如 @RequestMapping 等等,OpenFeign 的 @FeignClient 可以解析Spring MVC 的 @RequestMapping 注解下的接口,并通过动态代理的方式生产实现类 ,实现类中做负载均衡并且低哦用其他服务。
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
五、Openfeign服务调用
新建cloud-consumer-feign-order80
5.1 引入Pom依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Opnfeign默认整合了Ribbon。
5.2配置Application.yml
server:
port: 80
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
5.3主启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderFeignMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderFeignMain80.class, args);
}
}
5.4业务类
业务类逻辑接口+@FeignClient配置调用provider服务新建PaymentFeignService接口并新增注解@Feignclient
@FeignClient(name = "cloud-payment-service")
public interface PaymentFeignService {
@GetMapping("/payment/get/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
@GetMapping("/payment/feign/timeout")
String paymentFeignTimeOut();
}
5.5Controller
@RestController
@Slf4j
public class OrderFeignController {
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
return paymentFeignService.getPaymentById(id);
}
@GetMapping("/consumer/payment/feign/timeout")
public String paymentFeignTimeOut(){
return paymentFeignService.paymentFeignTimeOut();
}
}
5.6测试
启动Eureka,启动被调用的微服务,再启动80端口的调用方:
访问 http://localhost/consumer/payment/get/98
,负载均衡OK!
六、Openfeign 超时控制
# 设置 feign 客户端超时时间(OpenFeign 默认支持 ribbon)
ribbon:
# 值的是建立链接所用的时间,适用于网络状况正常的情况下, 两端链接所用的时间
ReadTimeout: 5000
# 指的是建立链接后从服务器读取可用资源所用的时间
ConectTimeout: 5000
微服务提供方新增模拟超时方法:
PaymentFeignService中新增对应接口方法:
Controller中增加对应方法:
在服务提供方本地测试:访问:localhost:8001/payment/feign/timeout
:3秒后返回结果如下:
使用Feign在80端口调用8001端口的服务:访问:localhost/consumer/payment/feign/timeout
因为OpenFeign默认等待时间为1秒,但是服务端处理需要超过1秒,导致Feign客户端不再等待,直接返回报错。为了避免这种情况,有时候需要设置Feign客户端的超时控制。
修改Application.yaml:
# 超时配置
ribbon:
ReadTimeout: 5000
ConnectTimeout: 5000
重启80服务,再次访问localhost/consumer/payment/feign/timeout
,3秒后返回信息
七、OpenFeign日志打印
Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Fegin 中 HTTP 请求的细节。说白了就是对Feign 接口的调用情况进行监控和输出。
7.1日志级别
-
NONE:默认的,不显示任何日志
-
BASIC:仅记录请求方法、URL、响应状态码以及执行时间
-
HEADERS:除了BASIC 中自定义的信息外,还有请求和响应的信息头
-
FULL:除了HEADERS中定义的信息外, 还有请求和响应的正文以及元数据。
7.2新增配置类:(指定日志级别)
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
7.3Application.yaml开启日志,同时指定监控的接口
logging:
level:
# feign日志以什么级别监控哪个接口
pers.zhang.springcloud.service.PaymentFeignService: debug
启动服务,访问localhost/consumer/payment/get/98