一、OpenFeign介绍
在Spring Cloud中,OpenFeign是⼀个声明式的HTTP客户端,它的作用是用于与RESTful API进行通信。相比于RestTemplate,OpenFeign的优势在于:
-
更加简洁的代码:使用OpenFeign,只需要定义⼀个接口,而不需要写任何实现代码。在接口上使用注解即可描述API的细节,OpenFeign会自动生成实现类并处理所有的HTTP细节。
-
更好的可读性和可维护性:OpenFeign使用注解来描述API,这使得代码更加易于阅读和理解。此外,OpenFeign的接口和实现分离,使得代码更加易于维护。
-
内置的负载均衡:OpenFeign内置了负载均衡功能,可以与Spring Cloud的服务发现组件(如Nacos)集成,从而自动地选择合适的服务实例进行请求。这使得在分布式系统中进行服务调用更加容易。
-
更加灵活的扩展性:OpenFeign是高度可配置的,可以通过自定义的编码器和解码器来处理不同的请求和响应格式。同时,OpenFeign还⽀持自定义的拦截器来实现更加复杂的请求和响应处理逻辑。
二、OpenFeign与Netflix Feign
OpenFeign是Spring Cloud项目中的⼀个模块,它是基于Feign开发的,可以看作是对Feign的进⼀步封装和增强。Feign是⼀个声明式、模板化的HTTP客户端,它的目标是简化HTTP API开发。OpenFeign在Feign的基础上增加了对Spring MVC注解、Spring Boot自动配置等特性的⽀持,并且集成了SpringCloud的服务发现和负载均衡功能。相比于Feign,OpenFeign更适合在Spring Cloud微服务架构中使用。
三、如何使用OpenFeign
在消费者端引入OpenFeign
先添加依赖:
<!-- 在使用者方引入OpenFeign实现服务间Rest通信 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>3.1.3</version>
</dependency>
在Application应用入口增加@EnableFeignClients
@SpringBootApplication
@EnableFeignClients //开启OpenFeign实现服务间REST通信
public class ArticleServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ArticleServiceApplication.class, args);
}
}
准备实体类
创建接口,定义传输细节
//这是一个OpenFeign客户端,video-service是数据提供方在nacos中注册的微服务名
@FeignClient("video-service")
public interface VideoFeignClient {
//访问video-service的/video地址
@GetMapping("/video")
Video findByArticleId(@RequestParam("articleId") Long articleId);
}
通过测试用例验证通信
@SpringBootTest
class ArticleServiceApplicationTests {
@Resource
private VideoFeignClient videoFeignClient;
@Test
public void testFindByArticleId(){
Video video = videoFeignClient.findByArticleId(1649L);
System.out.println(video);
}
}
注意:需要将 ”视频服务“ 和 ”文章服务“ 注册到Nacos!!!
四、Spring Cloud OpenFeign使用细节
可配置项列表
五、使用HttpClient 5替换URLConnection
OkHttpClient和Apache HttpClient 5的Feign客户端可以通过将spring.cloud.openfeign.okhttp.enabled或spring.cloud.openfeign.httpclient.hc5.enabled设置为true来使用,并将它们放在类路径上。您可以通过提供org.apache.hc.client5.http.impl.classic.CloseableHttpClient类型的bean来自定义所使用的HTTP客户端,当使用Apache HC5时。
引入依赖:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
<version>12.1</version>
</dependency>
修改配置文件:
spring.cloud.openfeign.httpclient.hc5.enabled=true
您还可以通过在spring.cloud.openfeign.httpclient.xxx属性中设置值来进⼀步自定义http客户端。以httpclient为前缀的那些属性将适用于所有客户端,以httpclient.hc5为前缀的那些属性将适用于ApacheHttpClient 5,以httpclient.okhttp为前缀的那些属性将适用于OkHttpClient。您可以在附录中找到可自定义的完整属性列表。
从Spring Cloud OpenFeign 4开始,不再⽀持Feign Apache HttpClient 4。我们建议使用Apache HttpClient 5代替。
六、超时处理
我们可以在默认客户端和命名客户端上配置超时。OpenFeign使用两个超时参数:
-
connectTimeout:可以防止由于长时间的服务器处理时间而阻塞调用方。
-
readTimeout:从连接建立时开始应用,当返回响应时间过长时会触发它。
如果服务器未运行或不可用,则包会被拒绝连接。通信将以错误消息或回退方式结束。如果connectTimeout设置得⾮常低,这可能会在之前发生。执行查找并接收这样的数据包所需的时间构成了此延迟的重要部分。它取决于涉及DNS查找的远程主机,因此可能会发生变化。
七、OpenFeign请求/响应压缩
您可以考虑为Feign请求启用请求或响应GZIP压缩。您可以通过启用以下属性之⼀来实现:
spring.cloud.openfeign.compression.request.enabled=true
spring.cloud.openfeign.compression.response.enabled=true
Feign请求压缩为您提供了类似于您为Web服务器设置的设置:
spring.cloud.openfeign.compression.request.enabled=true
spring.cloud.openfeign.compression.request.mime-types=text/xml,application/xml,application/json
spring.cloud.openfeign.compression.request.min-request-size=2048
spring.cloud.openfeign.compression.request.enabled=true:启用OpenFeign客户端请求压缩,默认值为false。如果设置为true,则客户端将在请求时启用压缩。
spring.cloud.openfeign.compression.request.mime-types=text/xml,application/xml,application/json:配置⽀持压缩的请求的MIME类型列表。默认情况下,Spring Cloud OpenFeign仅⽀持application/json类型的请求压缩。通过此配置,您可以添加其他MIME类型以启用压缩。
spring.cloud.openfeign.compression.request.min-request-size=2048:配置压缩请求的最小字节数。如果请求大小小于此值,则不会进行压缩处理。默认值为2048字节。
这些配置允许您在使用Spring Cloud OpenFeign进行客户端请求时启用压缩功能,以减少网络传输量,从而提高应用程序性能。
由于OkHttpClient使用“透明”压缩,如果存在content-encoding或accept-encoding头,则禁用它,
因此当feign.okhttp.OkHttpClient存在于类路径上并且spring.cloud.openfeign.okhttp.enabled设置为true时,我们不启用压缩。
八、OpenFeign日志记录
每个创建的Feign客户端都会创建⼀个记录器。默认情况下,记录器的名称是用于创建Feign客户端的接口的完整类名。Feign日志记录仅对DEBUG级别做出响应。
配置文件
# 日志级别低于warn的日志不会输出,方便我们观察OpenFeign输出日志
logging.level.root=warn
# 单独设置OpenFeign客户端的日志debug
# 虽然debug级别低于warn,但是我们单独指定的话,OpenFeign客户端依然会输出
logging.level.com.dw.articleservice.client: debug
Feign配置类
@Configuration
public class FeignConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.BASIC;
}
}
应用配置类
@FeignClient(value = "provider-service",configuration = FeignConfiguration.class)
public interface VideoClient {
@GetMapping("/video")
Video findByArticleId(@RequestParam("articleId") Long articleId);
}
您可以每个客户端配置Logger.Level对象,告诉Feign要记录多少。选择如下:
-
NONE,无日志记录(默认)。
-
BASIC,仅记录请求方法、URL、响应状态代码和执行时间。
-
HEADERS,记录基本信息以及请求和响应头。
-
FULL,记录请求和响应的头、正文和元数据。
例如,以下内容将Logger.Level设置为FULL:
@Configuration
public class FeignConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
各种情况的日志输出(看控制台)
NONE(啥都没有)
BASIC(仅记录请求方法、URL、响应状态代码和执行时间)
HEADERS(记录基本信息以及请求和响应头)
FULL(记录请求和响应的头、正文和元数据)
九、@FeignClient转发到URL
示例:
@FeignClient(value = "video-service", url = "localhost:8001", configuration = FeignConfig.class)
public interface VideoClient {
@GetMapping("/video")
Video findByArticleId(@RequestParam("articleId") Long articleId);
}
由于使用url指定了服务节点来处理OpenFeign发出去的请求,所以负载均衡不会执行,此处可通过控制台输出观察。
有负载均衡的情况:
使用了url属性时,不会有以上内容出现,相当于指定使用某台服务器,不存在负载均衡。