一、为什么需要使用Fegin
引言:在我们使用nacos的时候是不是也有一种服务调用的方法那个时候我们使用到RestTemplate去调用远程的服务,但是我们看下面的一个例子就可以知道RestTemplate这种方式对于维护和后期代码上来说是不合理的,以为会是代码可读性和维护性变得很差。
通过上面的图片我们可以看出来如果当你需要改变这个服务名的时候,你会发现你需要改的地方很多很多,而且每个请求都需要写一个url的话看起来也不是很顺眼也不符合编程写代码的习惯,所以这个时候就有个中间件出现了也就是我们的Fegin。
但是我们为什么使用Fegin呢?
Feign可以做到使用 HTTP 请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求,它像 Dubbo一样,Consumer直接调用接口方法调用 provider,而不需要通过常规的 Hip Client 构造请求再解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。
二、Fegin的基本使用
第一步:引入OpenFegin的maven依赖到pom.xml文件中
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.9.RELEASE</version></dependency>
第二步:在spring boot的启动类上加上注解启动OpenFegin
package com.ltx.nacosconsumer;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableDiscoveryClient
//openFegin注解
@EnableFeignClients
public class NacosConsumerApplication {public static void main(String[] args) {SpringApplication.run(NacosConsumerApplication.class, args);}}
第三步:编写OpenFegin对应的要调用的远程服务的client,并且在client接口中定义好需要访问远端的接口。
package com.ltx.nacosconsumer.demos.clients;import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;@FeignClient("provider")//括号里面的远端的服务名
public interface ConsumerClient {@GetMapping(value = "/t")//需要访问的远程的controller的访问地址String test();
}
第四步:在当前服务的controller中直接使用OpenFegin远程接口调用,直接的使用Client调用远程的接口就可以不使用之前的RestTemplate的那种需要写url的方法了。
package com.ltx.nacosconsumer.demos.controller;import com.ltx.nacosconsumer.demos.clients.ConsumerClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ConsumerController {@Autowiredprivate ConsumerClient consumerClient;@GetMapping(value = "/test")public String test() {return consumerClient.test();}
}
第五步:测试调用,我在provider中写的t方法其实就是返回一个字符串。
三、Fegin的自定义配置
Fegin的配置大概有下面的几种,但是我们一般使用到的Fegin的配置基本上就是日志级别的配置。
配置项 | 类型 | 作用与说明 |
---|---|---|
日志级别 | Logger.Level | 控制Feign客户端的日志输出级别。可选值:NONE、BASIC、HEADERS、FULL。 |
超时配置 | int | 设置Feign客户端的请求超时时间(毫秒)。 |
重试机制 | RetryPolicy | 配置重试策略,包括重试次数和重试间隔。 |
负载均衡 | LoadBalancer | 配置负载均衡策略,通常与Ribbon集成。 |
请求头配置 | Map<String, String> | 为Feign客户端配置自定义的请求头信息。 |
请求参数配置 | Map<String, Object> | 配置Feign客户端的请求参数,包括路径参数、查询参数、表单参数等。 |
解码器和编码器 | Decoder/Encoder | 配置Feign客户端使用的解码器和编码器,进行数据序列化和反序列化。 |
拦截器 | RequestInterceptor | 配置请求拦截器,在请求发送前后进行自定义处理。 |
日志级别分类
日志级别 | 作用 | 基本说明 |
---|---|---|
NONE | 无日志 | 不记录任何日志信息,这是默认值。 |
BASIC | 基础日志 | 记录请求的方法、URL以及响应状态码和执行时间。 |
HEADERS | 头信息日志 | 在BASIC的基础上,额外记录了请求和响应的头信息。 |
FULL | 详细日志 | 记录所有请求和响应的明细,包括头信息、请求体、元数据。 |
Java代码方式实现日志配置,自定义一个配置类DefaultFeignConfiguration。
package com.ltx.nacosconsumer.demos.logger;import feign.Logger;
import org.springframework.context.annotation.Bean;public class DefaultFeignConfiguration {@Beanpublic Logger.Level logLevel(){return Logger.Level.BASIC;// 请求和响应的日志}
}
1、如果要全局生效,将其放到启动类的@EnableFeignClients这个注解中:
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class)//开启Feign的功能
2、如果是局部生效,则把它放到对应的@FeignClient这个注解中:
@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class)
四、Fegin性能优化
OpenFeign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:
URLConnection:默认实现,不支持连接池
Apache HttpClient :支持连接池
OKHttp:支持连接池
引入Apache HttpClient依赖
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-httpclient --><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency><!--负载均衡--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
配置连接池
# 开启openfeign对HttpClient的支持
spring.cloud.httpclientfactories.apache.enabled=true
# 最大的连接数
feign.httpclient.max-connections=200
# 每个路径的最大连接数
feign.httpclient.max-connections-per-route=50
五、Fegin在实际使用
因为其实在很多业务场景中可能都会重复使用到一个业务中的代码可能会导致,每个业务中都会包含了一个FeginApi的类会导致整个项目的冗余度变高,所以这个时候有一种做法就是把FeginApi的代码全部都抽离处理,如何在其他的需要用到的项目中引入Fegin的包就可以直接的使用FeginApi进行远程服务调用。