文章目录
Open Feign 是什么
Feign 是声明性Web服务客户端。它使编写Web服务客户端更加容易。
要使用Feign,请创建一个接口并对其进行注释。它具有可插入注释支持,包括Feign注释和JAX-RS注释。
Feign还支持可插拔编码器和解码器。Spring Cloud添加了对Spring MVC注释的支持,并支持使用HttpMessageConverters
Spring Web中默认使用的注释。
Spring Cloud集成了Ribbon和Eureka以及Spring Cloud LoadBalancer,以在使用Feign时提供负载平衡的http客户端。
简言之
Feign可以进行远程服务调用
Feign 采用的是基于接口的注解
Feign 整合了ribbon,具有负载均衡的能力
Feign整合了Hystrix,具有熔断的能力
Open Feign实现服务调用
注册中心与服务提供者,请看之前的案例。
feign相当于一个客户端即(RestTemplate + Ribbon),所以我们只需要建立一个模块来封装这个客户端即可,也就相当于我们的消费者了
1、建Module
cloud-consumer-feign-order80
2、改pom
<dependencies>
<!--open feign整合包,feign中也包含了ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--删除掉entities后,将公用代码打包放到公共模块中,引入模块-->
<dependency>
<groupId>com.lejia.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3、写yml
server:
port: 80
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true open feign作为客户端就不需要注册了
register-with-eureka: false
#是否从EurekaServe抓取已有的注册信息,默认为true
# 单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
# defaultZone: http://localhost:7001/eureka 单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
instance:
instance-id: order80
prefer-ip-address: true #默认false,显示IP地址
4、主启动
在主启动上添加注解@EnableFeignClients ,开启feign远程调用功能
@SpringBootApplication
@EnableFeignClients //添加feign客户端
@EnableDiscoveryClient
public class OrderFeignMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderFeignMain80.class,args);
}
}
5、业务类
新建远程调用接口
package com.lejia.springcloud.service;
PaymentFeignService.java
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE") //关联到注册中心上需要调用的服务名称
public interface PaymentFeignService {
//调用服务提供者所暴露出来的接口
@GetMapping("/payment/get/{id}")
public CommentResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
新建业务层
package com.lejia.springcloud.controller;
OrderFeignController.class
@RestController
@Slf4j
@RequestMapping("/consumer/payment")
public class OrderFeignController {
//feign服务接口
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping("/feign/get/{id}")
public CommentResult<Payment> paymentById(@PathVariable("id") Long id){
return paymentFeignService.getPaymentById(id);
}
}
6、项目结构图
7、测试
在地址栏输入客户端所提供的接口
http://localhost/consumer/payment/get/1
我们发现Open Feign已经自动开启了负载均衡功能,并默认以轮询作为负载策略
Open Feign实现其他负载均衡规则
我们在上面可以看出,OpenFeign默认集成了ribbon并且以轮询作为默认的负载规则现在我们尝试一下其他的负载策略
首先我们需要在主启动类的上一个文件夹下新建一个包
新建一个负载IRule规则,将它声明为一个@Bean
package com.lejia.myrole;
@Configuration
public class MySelfRule {
@Bean
public IRule getIRule(){
return new RandomRule();
}
}
在主启动类上开启我们自定义的配置
//name为注册中心上服务提供者集群的名称,configuration为我们自定义的规则
@RibbonClient(name="CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
public class OrderFeignMain80 {
}
再次启动重新测试,发现随机策略已经成功的配置了。
总结:
经过两种服务调用的测试(Open Feign)与(RestTemplate + Ribbon)我们可以发现,在一般的使用中,两者并没有太多的不同。
自定义策略可以查看以下博客或者自行查找ribbon官网文档
Open Feign超时调用测试
feign的超时调用时间默认为1s中。
当我们访问请求时,如果服务端的响应时间超过1秒以后,客户端直接会返回超时错误。
测试方法
1、在服务提供者8001/8002/8003中添加方法
目的是使请求在服务端响应3秒后再返回给客户端
@GetMapping("/payment/feign/timeout")
public String getPaymentFeignTimeout(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "调用的端口为"+serverPort;
}
2、将方法添加到80服务的feign访问接口中
package com.lejia.springcloud.service;
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
@GetMapping("/payment/get/{id}")
public CommentResult<Payment> getPaymentById(@PathVariable("id") Long id);
@GetMapping("/payment/feign/timeout")
public String getPaymentFeignTimeout();
}
3、暴露给用户的接口
package com.lejia.springcloud.controller;
public class OrderFeignController {
...
@GetMapping("/feign/timeout")
public String getPaymentTimeout(){
return paymentFeignService.getPaymentFeignTimeout();
}
}
4、测试
示例,服务端延时3秒响应,此时客户端响应一秒钟后就报超时错误
5、解决feign超时连接问题
在80客户端的application.yml配置文件中设置feign的超时请求时间即可
# 设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
# 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间
ReadTimeout: 5000
# 指的是建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
ps : 客户端经过设置最久等待时间为10s
此时,再次测试,客户端请求经过三秒后得到了服务器的响应
Open Feign日志打印监控功能
Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。
总的来说就是对Feign接口的调用情况进行监控和输出
Feign日志级别
- NONE : 默认的,不显示任何日志;
- BASIC : 仅记录请求方法、URL、响应状态码及执行时间;
- HEADERS : 除了BASIC中定义的信息之外,还有请求和响应的头信息;
- FULL : 除了HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。
配置详解
在客户端中添加配置类FeignConfig
package com.lejia.springcloud.config;
新建FeignConfig.class
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL; //Full级别
}
}
在yml中添加配置开启日志
logging:
level:
#Feign日志以什么级别监控那个接口
com.lejia.springcloud.service.PaymentFeignService: debug
查看日志
再次发送请求测试,我们可以看到,feign记录的接口日志非常全面
感谢你的访问,你的每一个点赞都是对我最大的帮助!