Feign详解与实战
一、概述
在前一章介绍了Ribbon的用法,在使用Ribbon是通过RestTemplate调用其他服务的API时,所有参数必须在请求的URL中进行拼接。如果参数过多,拼接请求字符串会导致效率下降。Spring Cloud提供另外一种调用API的解决方案,既使用Spring Cloud Feign。
二、什么是Feign
Feign是一种负载均衡的HTTP客户端,它封装了Ribbon。使用Feign调用API就像调用本地方法一样。从而避免了调用微服务时,需要不断封装/解析Json数据的繁琐步骤。
Feign是一个声明似的Web客户端,它使得编写Web服务客户端变得更容易。使用Fegin创建一个接口并对它进行注解。它具有可插拔的注解支持包含Fegin注解与JAX-RS注解,Feign还支持可插拔的编码器与解码器,Spirng Cloud增加了对Spring MVC的注解功能。Feign默认集成了Ribbon,所以Fegin默认就实现了负载均衡效果。
三、Feign特性
- 支持可插拔的HTTP编码器和解码器
- 支持Hystrix和它的Fallback;
- 支持Ribbon的负载均衡;
- 支持HTTP请求和响应的压缩。
四、Feign简单使用
3.1 Feign使用步骤
- 引入依赖
- 在启动类上添加注解
- 编写FeignClient接口
- 使用Feign发起http请求
- 配置Feign日志
3.2 Feign具体使用
1. 引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 启动类上添加注解
@MapperScan("com.goyeer")
@SpringBootApplication
@EnableFeignClients
public class GoyeerApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
3.编写FeignClient接口
@FeignClient("orderservice")
public interface OrderClient {
@GetMapping("/Order/findById")
Order findById(@PathVariable("orderId") Long orderId);
}
五、使用Feign发起http请求
5.1 Maven导入Feign配置,并集成Jackson
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 用于解析数据 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>9.7.0</version>
</dependency>
5.2 Feign发送路径和方法设置
@RequestLine("GET /user/getone?arkOrgId={arkOrgId}&userId={userId}")
JSONObject getOneEmployee(@Param("orgId") String orgId,@Param("userId") String userId);
@RequestLine("POST /user/add")
@Headers("Content-Type: application/json")
@Body("{body}")
JSONObject saveEmployee(@Param("body") EmployeeDTO employeeDTO);
5.3 调用Feign.bulider()指定请求uri并且调用接口中的方法
public class App{
public static void main(String[] args){
EmloyeeAPI emloyeeAPI = Feign.builder().target(EmloyeeAPI.class,"http://localhost:8088");
String result = emloyeeAPI.getOneEmployee("110","1110");
System.out.println(result);
}
}
六、Feign接口常用注解
注解 | 类型 | 说明 |
---|---|---|
@RequestLine | Method | 定义其请求方法和请求路径(UriTemplate)。请求路径以斜杠开始,中间可以使用{变量名称},表达式的值由@Param注解提供。 |
@Param | Parameter | 定义变量模板,可通过表达式{变量名称}引用变量的值 |
@Headers | Method,Type | 定义请求头,可以使用{变量名},表达式的值由@Param注解提供。 |
@QueryMap | Parameter | 定义Map或者Pojo类型参数。 |
@HeaderMap | Parameter | 定义Map类型的请求头 |
@Body | Method | 对@Param扩展,配合@Headers使用可定义JSON、XML类型参数 |
七、Feign接口与常用注解
7.1 target方法
指定接口类型和URL地址接口Http代理对象,从而通过代理对象调用方法发送HTTP请求。
7.2 client方法
Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请求。
7.3 options方法
指定连接超时时长及响应超时时长,单位毫秒。
7.4 retryer方法
指定重试策略,参数分别是最小时间,最大时间,重连次数。
7.5 encoder()/decode()方法
指定编码/解码方式默认是String
7.6 logger() logLevel()
指定日志和日志等级、可配置SLF4J等
7.7 @EnableFeignClients
用来开启Feign
7.8 @FeignClient
标记要用Feign来拦截的请求接口
7.9 value,name
value 和 name 的作用一样,如果没有配置url那么配置的值将作为服务名称,用于服务发现。反之只是一个名称。
7.10 serviceId
serviceId已经废弃了,直接使用name即可。
7.11 contextId
解决Bean的名称冲突了。
7.12 url
url用于配置指定服务的地址,相当于直接请求这个服务,不经过Ribbon的服务选择。像调试等场景可以使用。
7.13 decode404
当调用请求发生404错误时,decode404的值为true,那么会执行decoder解码,否则抛出异常。
7.14 configuration
configuration是配置Feign配置类,在配置类中可以自定义Feign的Encoder、Decoder、LogLevel、Contract等。
7.15 fallback
定义容错的处理类,也就是回退逻辑,fallback的类必须实现Feign Client的接口,无法知道熔断的异常信息。
7.16 fallbackFactory
也是容错的处理,可以知道熔断的异常信息。
7.17 path
path定义当前FeignClient访问接口时的统一前缀,比如接口地址是/user/get, 如果你定义了前缀是user, 那么具体方法上的路径就只需要写/get 即可。
7.18 primary
primary对应的是 @Primary 注解,默认为 true,官方这样设置也是有原因的。当我们的Feign实现了fallback后,也就意味着Feign Client有多个相同的Bean在Spring容器中,当我们在使用@Autowired进行注入的时候,不知道注入哪个,所以我们需要设置一个优先级高的,@Primary 注解就是干这件事情的。
7.19 qualifier
qualifier 对应的是 @Qualifier 注解,使用场景跟上面的primary关系很淡,一般场景直接 @Autowired 直接注入就可以了。
八、Feign的日志级别
8.1 Feign的日志级别
- NONE(默认):不记录任何日志,性能最佳,使用与生产环境。
- BASIC:仅记录请求方法,URL、响应状态代码以及执行时间,适用于生产环境追踪问题;
- HEADERS:在BASIC级别的基础上,记录请求和响应的Header;
- FULL:记录请求和响应的Header\Body和元数据,使用于开发测试定位问题。
8.2 Feign日志配置方法
-
配置类全局配置
在工程中增加一个配置类、如下设定日志级别,可作为全局配置
@Configuration public class FeignConfig{ @Bean public Logger.Level level(){ return Logger.level.FULL; } }
-
配置类局部配置
首先将FeignConfig的@Configuration注解去掉,否则将是全局配置。
在@FeignClient中configuration属性赋值为FeignConfig.class
@FeignClient(path = "/employee", value = "provider", configuration = FeignConfig.class) public interface UserService { @RequestMapping("/list") List<String> findEmployee(); }
-
配置文件指定微服务配置
在配置文件中,加入如下配置,provider为服务端服务名,改配置只对调用provider服务时生效。
feign.client.config.provider.loggerLevel=BASIC
九、Feign原理
4.1 Feign服务调用的工作原理可以总结为以下几个步骤:
- 首先通过@EnableFeignCleints注解开启FeignCleint。
- 根据Feign的规则实现接口,添加@FeignCleint注解。程序启动后,会扫描所有有@FeignCleint的类,并将这些信息注入到ioc容器中。
- 注入时从FeignClientFactoryBean.class获取FeignClient。
- 当接口的方法被调用时,通过jdk的代理,来生成具体的RequesTemplate,RequesTemplate生成http的Reques。
- Request交给Client去处理,其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp。
- Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡。
4.2 Feign整体流程图
十、Feign与Ribbon异同
Ribbon与Feign都是实现负载均衡的组件,Feign的本质是Ribbon,是基于Ribbon的实现。都是加在消费端的注解,让消费端可以调用其他生产者的服务。
Fegin与Ribbon的两者的区别
- 启动类使用的注解不同,Ribbon用的是@RibbonClinet,Feign用的是@EnableFeignClients。
- 服务的指定位置不同,Ribbon 是在@RibbonClient 注解上声明,Feign 则是在定义抽象方法的接口中使用@FeignClient 声明。
- 调用方式不同,Ribbon 需要自己构建 http 请求,模拟 http 请求然后使用 RestTemplate 发送给其他服务,步骤相当繁琐。
- Ribbon可配置负载均衡机制
十一、Feign与RestTemplate异同
-
RestTemplate
RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。文章来源:https://www.toymoban.com/news/detail-727532.html
- 添加相关注解参数即可,使用简单方便。
- 熔断节点易控制,方便后续基于业务作出相应调整。
- 异常捕获简单,同页面下添加对应方法即可。
- 请求更贴近httpclient,使用更有熟悉感。
- 灵活性高但是消息封装臃肿。
-
Feign
一种负载均衡的HTTP客户端, 使用Feign调用API就像调用本地方法一样,从避免了 调用目标微服务时,需要不断的解析/封装json 数据的繁琐。Feign是一个声明似的web服务客户端,Spring Cloud 增加了对 Spring MVC的注解,Spring Web 默认使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的负载均衡的HTTP客户端 Feign。文章来源地址https://www.toymoban.com/news/detail-727532.html
- 编写方式优雅,基于面向接口的风格,但是开发起来较为繁琐。
- yml需要添加配置启动hystrix组件。
- 需要创建对应类来执行fallback方法。
- 捕获异常信息和不捕获异常实现的接口不同。
- 需要在feign注解上作出相应参数配置。
- feign中作出任何操作需要创建各种类来对应不同参数
十二、Feign和OpenFeign异同
-
相同点
- Feign 和 OpenFeign 都是 Spring Cloud 下的远程调用和负载均衡组件。
- Feign 和 OpenFeign 作用一样,都可以实现服务的远程调用和负载均衡。
- Feign 和 OpenFeign 都对 Ribbon 进行了集成,都利用 Ribbon 维护了可用服务清单,并通过 Ribbon 实现了客户端的负载均衡。
- Feign 和 OpenFeign 都是在服务消费者(客户端)定义服务绑定接口并通过注解的方式进行配置,以实现远程服务的调用。
-
不同点
- Feign 和 OpenFeign 的依赖项不同,Feign 的依赖为 spring-cloud-starter-feign,而 OpenFeign 的依赖为 spring-cloud-starter-openfeign。
- Feign 和 OpenFeign 支持的注解不同,Feign 支持 Feign 注解和 JAX-RS 注解,但不支持 Spring MVC 注解;OpenFeign 除了支持 Feign 注解和 JAX-RS 注解外,还支持 Spring MVC 注解
到了这里,关于【Spring Cloud系列】Feign详解与实战的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!