今天更新一篇关于微服务应用中两个服务间使用feign请求方式时,遇到请求或响应数据量很大时,如何提升性能优化的问题。这也是基于自己的实际应用场景做的技术分享,如有问题欢迎@bozy(tym_ly@126.com)讨论。
业务场景: A服务 去请求 B服务,采用Feign请求方式。
graph TD
服务A --> 服务B
如果有细心的朋友就会发现,B服务在处理完自身业务打印日志时间点 与 A服务接收到响应数据之间时间差会随着响应数据的增大而增大。这是因为数据的传输占用网络带宽导致的,提升响应时间的一个解决思路就是把响应数据变小,可采用数据压缩技术,以提升网络传输时间耗时。
其实容器和feign框架本身是支持数据压缩的,只需要我们手动开启一下配置即可。
服务A作为请求端需要的一般配置如下:
server:
compression:
enabled: true
feign:
compression:
request:
mime-types:
- application/json
min-request-size: 2048
代码实现上有三点需要注意:
- 使用
feign-httpclient库进行接口间的请求调用,通过请求连接的资源池化有效提升请求处理性能; - 服务A侧的feign接口返回类型定义使用
ResponseEntity<byte[]>; - 请求服务B时需要在header中添加
Accept-Encoding:gzip,其目的是告知服务B需要对响应数据进行压缩处理;
另外,服务A在接收到接口响应数据后,也是要判断一下服务B有没有给做压缩,毕竟还涉及到数据的解压缩处理,处理逻辑是不一样的。
服务B作为服务端配置会少一些,如下:
server:
compression:
enabled: true
min-response-size: 1024
需要注意的是,如果是想根据响应数据的大小设定一个是否需要压缩的阀值,有时候我们在设置了min-response-size的值之后是不会生效的,这也许是因为你在服务B侧的接口最后返回数据时使用的是MappingJackson2HttpMessageConverter造成的,进而容器在检查时认为需要对响应数据进行压缩的两个因素:Accept-Encoding 和 Content-Length 都满足,所以给你的数据进行了压缩。此时如果想让你设置的min-response-size值起作用,其中一个解决办法是让服务B侧的接口方法返回值类型定义为字符串String,让其走StringHttpMessageConverter消息处理。
好了,以上部分就是今天要分享给大家的技术内容。
如想了解底层运行机制可参阅:CompressionConfig#useCompression、Http11Processor#isCompressible