spring cloud之feign(四)
来源:互联网 发布:java 调用 jmeter api 编辑:程序博客网 时间:2024/05/19 17:58
1.Feign简介
Feign是一个声明式的Web服务客户端。这使得Web服务客户端的写入更加方便 要使用Feign创建一个界面并对其进行注释。它具有可插入注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud增加了对Spring MVC注释的支持,并使用Spring Web中默认使用的HttpMessageConverters
。Spring Cloud集成Ribbon和Eureka以在使用Feign时提供负载均衡的http客户端。
在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection
、Apache的Http Client
、Netty的异步HTTP Client, Spring的RestTemplate
。但是,用起来最方便、最优雅的还是要属Feign了。
Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。
现在为止所进行的 有Rest Rest 服务调用实际上都会出现一个非常尴尬的局面,所有的数据调用和转换都必须由户自己来完成,而我们本身不擅 所有的数据调用和转换都必须由户自己来完成,我们习惯的编程模式是:通过接口来实现业务 长这些,我们习惯的编程模式是:通过接口来实现业务 长这些,我们习惯的编程模式是:通过接口来实现业务 长,这可以通过feign来实现,Feign = RestTempate + HttpHeader Ribbon Eureka综合体 综合体 = 业务接口的自动实例化。
2.使用Feign
2.1 pom.xml中添加
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-cloud</artifactId> <groupId>com.alen</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <packaging>jar</packaging> <artifactId>feign-service</artifactId> <dependencies> <!--eureka client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!--feign支持--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
2.2 定义接口
为了让Feign知道在调用方法时应该向哪个地址发请求以及请求需要带哪些参数,我们需要定义一个接口:
package com.alen.service;import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;/** * 定义一个feign接口,通过@ FeignClient(“服务名”),来指定调用哪个服务 **/@FeignClient(value ="eureka-client")public interface HelloService { @RequestMapping("/hello") //必须显示的指定age,不显示还不行 String hello(@RequestParam("age") Integer age);}
A: @FeignClient
用于通知Feign组件对该接口进行代理(不需要编写接口实现),使用者可直接通过@Autowired
注入。
B: @RequestMapping
表示在调用该方法时需要向/group/{groupId}
发送GET
请求。
C: @PathVariable
与SpringMVC
中对应注解含义相同。
Spring Cloud应用在启动时,Feign会扫描标有@FeignClient
注解的接口,生成代理,并注册到Spring容器中。生成代理时Feign会为每个接口方法创建一个RequetTemplate
对象,该对象封装了HTTP请求需要的全部信息,请求参数名、请求方法等信息都是在这个过程中确定的,Feign的模板化就体现在这里。
在本例中,我们将Feign与Eureka和Ribbon组合使用,@FeignClient(name = "ea")
意为通知Feign在调用该接口方法时要向Eureka中查询名为ea
的服务,从而得到服务URL。
controller中调用这个接口
@RestControllerpublic class HelloController { @Autowired private HelloService helloService; /** * 通过Controller调用远程服务 * @param age * @return */ @RequestMapping("/hello") public String home(@RequestParam Integer age) { return helloService.hello(age); }}
2.3 启动类
@SpringBootApplication//通过注解@EnableEurekaClient 表明自己是一个eurekaclient.@EnableEurekaClient//开启Feign的功能@EnableFeignClientspublic class App { public static void main(String[] args) { SpringApplication.run(App.class, args); }}
2.4 application.properties文件
#端口server.port=8075eureka.instance.hostname=localhost#设置eureka服务器所在的地址,查询服务和注册服务都需要依赖这个地址。eureka.client.serviceUrl.defaultZone=http\://localhost\:8081/eureka/#这在以后的服务与服务之间相互调用一般都是根据这个namespring.application.name=feign-service#eureka.client.register-with-eureka=true#eureka.client.fetch-registry=true# 心跳时间,即服务续约间隔时间(缺省为30s)eureka.instance.lease-renewal-interval-in-seconds= 5# 发呆时间,即服务续约到期时间(缺省为90s)eureka.instance.lease-expiration-duration-in-seconds=15
Feign的源码实现的过程如下:
- 首先通过@EnableFeignCleints注解开启FeignCleint
- 根据Feign的规则实现接口,并加@FeignCleint注解
- 程序启动后,会进行包扫描,扫描所有的@ FeignCleint的注解的类,并将这些信息注入到ioc容器中。
- 当接口的方法被调用,通过jdk的代理,来生成具体的RequesTemplate
- RequesTemplate在生成Request
- Request交给Client去处理,其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp
- 最后Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡。
2.5 .Feign 相关配置
FeignFeignFeign Feign之中最为核心的作用就是将 Rest Rest 服务的信息转换为接口,但是在实际使用之中也需要 考虑到一些配置情况, 例如:数据压缩Rest Rest 的核心本质在于: JSON 数据传输( XMLXMLXML、文本),于是就必须思考一种情况,玩意 、文本),于是就必须思考一种情况,玩意 、文本),于是就必须思考一种情况,玩意 用户发送的数据很大呢? 所以这个时候可考虑修改 application.yml 配置文件对传输数据进行压缩; 配置文件对传输数据进行压缩;
feign: compression: request: mime-types: # 可以被压缩的类型# - text/xml# - application/xml# - application/json min-request-size: 2048 # 超过2048的字节进行压缩
2、 如果有需要则可以在项目之中开启 feign的相关日志信息(默认不开启) 的相关日志信息(默认不开启) :
修改 application.yml配置文件,追加日志追踪:
logging: level:# feign接口包所在位置 cn.mldn.service: DEBUG
修改 FeignClientConfig ,开启日志的输出:
@Configurationpublic class FeignClientConfig { @Bean public Logger.Level getFeignLoggerLevel() { return feign.Logger.Level.FULL ; } }
3. Feign的Encoder、Decoder和ErrorDecoder
Feign将方法签名中方法参数对象序列化为请求参数放到HTTP请求中的过程,是由编码器(Encoder)完成的。同理,将HTTP响应数据反序列化为java对象是由解码器(Decoder)完成的。
默认情况下,Feign会将标有@RequestParam
注解的参数转换成字符串添加到URL中,将没有注解的参数通过Jackson转换成json放到请求体中。注意,如果在@RequetMapping
中的method
将请求方式指定为POST
,那么所有未标注解的参数将会被忽略,例如:
@RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET)void update(@PathVariable("groupId") Integer groupId, @RequestParam("groupName") String groupName, DataObject obj);
此时因为声明的是GET请求没有请求体,所以obj
参数就会被忽略。
在Spring Cloud环境下,Feign的Encoder*只会用来编码没有添加注解的参数*。如果你自定义了Encoder, 那么只有在编码obj
参数时才会调用你的Encoder。对于Decoder, 默认会委托给SpringMVC中的MappingJackson2HttpMessageConverter
类进行解码。只有当状态码不在200 ~ 300之间时ErrorDecoder才会被调用。ErrorDecoder的作用是可以根据HTTP响应信息返回一个异常,该异常可以在调用Feign接口的地方被捕获到。我们目前就通过ErrorDecoder来使Feign接口抛出业务异常以供调用者处理。
Feign的HTTP Client
Feign在默认情况下使用的是JDK原生的URLConnection
发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistence connection
。我们可以用Apache的HTTP Client替换Feign原始的http client, 从而获取连接池、超时时间等与性能息息相关的控制能力。Spring Cloud从Brixtion.SR5
版本开始支持这种替换,首先在项目中声明Apache HTTP Client和feign-httpclient
依赖:
<!-- 使用Apache HttpClient替换Feign原生httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-httpclient</artifactId> <version>${feign-httpclient}</version> </dependency>
然后在application.properties
中添加:
feign.httpclient.enabled=true
总结
通过Feign, 我们能把HTTP远程调用对开发者完全透明,得到与调用本地方法一致的编码体验。这一点与阿里Dubbo中暴露远程服务的方式类似,区别在于Dubbo是基于私有二进制协议,而Feign本质上还是个HTTP客户端。如果是在用Spring Cloud Netflix搭建微服务,那么Feign无疑是最佳选择。
参考:http://blog.csdn.net/neosmith/article/details/52449921
https://springcloud.cc/spring-cloud-dalston.html#spring-cloud-feign
- spring cloud之feign(四)
- Spring Cloud之Feign入门
- 四、Spring Cloud 的 Feign 组件
- Spring Cloud实战(四)-Spring Cloud Netflix Feign
- Spring Cloud之Feign调用token丢失
- Spring Cloud feign
- Spring Cloud Feign诠释
- spring cloud-feign
- Spring Cloud Feign常见问题
- spring cloud Feign
- spring cloud feign
- Spring Cloud feign使用
- Spring Cloud Feign
- Spring Cloud Feign
- spring-cloud【Feign】
- spring cloud day03 【feign】
- Spring Cloud(四)服务提供者 Eureka + 服务消费者 Feign
- spring cloud 微服务之 Eureka与Feign
- oracle存储过程:游标使用,多重游标
- JavaScript验证cron表达式是否正确(返回错误信息)
- windows 10 adb 使用
- 数据结构 — 并查集的原理与应用
- es6 字符串嵌套拼接
- spring cloud之feign(四)
- WebSocket与消息推送
- oracle数据库安装问题:所选安装与指定Oracle主目录中已安装的软件冲突
- Objective-C指针、栈帧、栈
- 标准C语言各种时间函数用法
- chromium源代码结构
- 实现两个整数变量的交换
- shell 字符串为空和长度的判断
- 【资料合集】阿里巴巴开源技术汇总——内含115个软件与100+技术文档、PDF下载