Feign请求响应GZIP压缩技术提升接口数据传输性能

213 阅读2分钟

今天更新一篇关于微服务应用中两个服务间使用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    

代码实现上有三点需要注意:

  1. 使用feign-httpclient库进行接口间的请求调用,通过请求连接的资源池化有效提升请求处理性能;
  2. 服务A侧的feign接口返回类型定义使用ResponseEntity<byte[]>
  3. 请求服务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#useCompressionHttp11Processor#isCompressible