Spring-Cloud 组件之声明式服务调用Fegin
1. 什么是Feign?
Feign是Netflix开发的声明式、模板化的http客户端,
1.1 什么是声明式
Spring Cloud 的声明式调用, 可以做到使用 HTTP 请求远程服务时能就像调用本地
方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。
1.2 声明式调用的作用
它像 Dubbo 一样,consumer 直接调用接口方法调用 provider,而不需要通过常规的
Http Client 构造请求再解析返回数据。
它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细
节,更无需关注分布式环境开发。使发送请求不再拼接url那么麻烦。
2. Feign的使用
2.1 创建provider项目
2.1.1 修改pom文件
2.1.2 创建全局配置文件
2.1.3 编写controller代码
2.1.4 编写启动类
2.2 创建Feign接口
2.2.1 修改pom文件
2.2.2 编写feign接口
2.3 创建consumer项目
2.3.1 修改pom文件
2.3.2 创建全局配置文件
2.3.3 编写servcie接口
2.3.4 编写controller接口
2.4 创建pojo项目
2.4.1 创建pojo类
2.5 启动provider和consumer,并进行测试
3. 总结feign的三种传参方式
1)、restful风格
接口: @PathVarible("参数")
2)、pojo
接口: @RequestBody User user
provider: @RequestBody User user
post方式传递对象(和普通传递对象一致,feign默认为post传参)
get方式传递对象:需要将拆分开成对象的属性进行传参
3)、url传参
接口: @RequestParam("参数")
4. Feign接口的作用原理
Spring IOC容器(装接口)----->RequestTemplate(生成代理类)---->Request(发出请求)
4. 1、spring-cloud-netflix-core-1.3.6.RELEASE.jar
FeignClientsRegistrar.registerFeignClients():
首先检查启动类上是否有 @EnableFeignClients,如果有该注解,则扫描被 @FeignClient注解的接口,并且将这些接口存储到Spring IOC容器中,方便后续被调用。
2、feign-core-9.5.0.jar
调用方法时:ReflectiveFeign静态内部类FeignInvocationHandler
再调用SynchronousMethodHandler.invoke():
当定义的的Feign接口中的方法被调用时,通过JDK的代理方式为Feign接口生成了一个动态代理类,当生成代理时,
Feign会为每个接口方法创建一个RequestTemplate。该对象封装了HTTP请求需要的全部信息,如请求参数名,请求方法等信息都是在这个过程中确定的。
3、2、feign-core-9.5.0.jar
FeignClientsRegistrar.executeAndDecode():
发起请求时将RequestTemplate生成Request,然后把Request交给Client发出请求。
3.3 Client执行请求操作:
4.Feign 的性能优化
4.1 通过 Gzip 压缩算法,提升网络通信速度
4.1.1 什么是Gzip
gzip 是一种数据格式,采用用 deflate 算法压缩 data;gzip 是一种流行的文件压缩算法,应用十分广泛,尤其是在 Linux 平台。
当 Gzip 压缩到一个纯文本文件时,效果是非常明显的,大约可以减少 70%以上的文件大小。
4.1.2 Gzip的作用
网络数据经过压缩后实际上降低了网络传输的字节数,最明显的好处就是可
以加快网页加载的速度。网页加载速度加快的好处不言而喻,除了节省流量,改善用户的浏
览体验外,另一个潜在的好处是 Gzip 与搜索引擎的抓取工具有着更好的关系。例如 Google
就可以通过直接读取 gzip 文件来比普通手工抓取 更快地检索网页。
4.1.3 如何使用Gzip进行文件的传输
4.1.3.1 HTTP 协议中关于压缩传输的规定
第一:客户端向服务器请求中带有:Accept-Encoding:gzip, deflate 字段,向服务器表示,
客户端支持的压缩格式(gzip 或者 deflate),如果不发送该消息头,服务器是不会压缩的。
第二:服务端在收到请求之后,如果发现请求头中含有 Accept-Encoding 字段,并且支
持该类型的压缩,就对响应报文压缩之后返回给客户端,并且携带 Content-Encoding:gzip 消
息头,表示响应报文是根据该格式压缩过的。
第三:客户端接收到请求之后,先判断是否有 Content-Encoding 消息头,如果有,按该
格式解压报文。否则按正常报文处理。
4.1.3.2 Gzip 压缩的配置
1)配置 Consumer 通过 Feign 到 到 Provider 的请求与相应的 的 Gzip 压缩
2)对客户端浏览器的请求以及 Consumer 对 provider 的请求与响应做 Gzip 压缩
4.2 采用 Http 连接池,提升 Feign 的并发吞吐量
4.2.1 为什么 http 连接池能提升性能?
a. 两台服务器建立 http 连接的过程是很复杂的一个过程,涉及到多个数据包的交换,并
且也很耗时间。
b. Http 连接需要的 3 次握手 4 次分手开销很大,这一开销对于大量的比较小的 http 消
息来说更大。
4.2.2 优 化解决方案
a. 如果我们直接采用 http 连接池,节约了大量的 3 次握手 4 次分手;这样能大大提升吞
吐率。
b. feign 的 http 客户端支持 3 种框架;HttpURLConnection、httpclient、okhttp;默认是
HttpURLConnection。
c. 传统的 HttpURLConnection 是 JDK 自带的,并不支持连接池,如果要实现连接池的
机制,还需要自己来管理连接对象。对于网络请求这种底层相对复杂的操作,如果有可用的
其他方案,也没有必要自己去管理连接对象。
d. HttpClient 相比传统 JDK 自带的 HttpURLConnection,它封装了访问 http 的请求头,
参数,内容体,响应等等;它不仅使客户端发送 HTTP 请求变得容易,而且也方便了开发人
员测试接口(基于 Http 协议的),即提高了开发的效率,也方便提高代码的健壮性;另外
高并发大量的请求网络的时候,还是用“连接池”提升吞吐量。
4.3 http连接池的使用(本例使用HttpClient连接池)
4.3.1 创建项目(拷贝以上项目进行更改)
4.3.2 修改pom文件
4.3.3 修改全局配置文件
4.3.4 修改feign接口
4.3.4 测试
5. 查看口 微服务日志中记录每个接口 URL
5.1 使用方法
5.1.1 导入Logback.xml日志文件,并将输出级别改为debug
5.2 在启动类中添加一个方法
5.3 测试,查看控制台日志情况
---->>为请求的信息
<<----为响应的信息