微服务设计指导-feignclient的compression参数导致报文返回为gzip格式带来的坑

Posted TGITCIC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务设计指导-feignclient的compression参数导致报文返回为gzip格式带来的坑相关的知识,希望对你有一定的参考价值。

背景

在实际对接项目中,我们的支付网关的feignclient开启了compression-on,这是标准的正确的。如下配置代码片段

feign:
   okhttp:
      enabled: true
   httpclient:
      enabled: false
      max-connections: 1000
      max-connections-per-route: 100
   compression:
      request:
         mime-types: text/xml,application/xml,application/json
         min-request-size: 2048
         enabled: true
      response:
         enabled: true

中台内,我们自己的tomcat、springboot jvm、我们的K8S容器层、我们的NG全部带着优化参数和配置,因此在像中台内或者是标准的微服务或者是标准的HTTP Restful服务,feignclient均能正确解析。


但是,如果是第三方的tomcat,ng无任何配置,且没在代码里标明这是一个标准的以json返回的restful api,而是用的代码默认的。那么第三方返回的整个报文会走“自适应”匹配模式,所以才导致了一些报文是json返回一些报文变成了gzip流返回。而对于gzip流的返回格式如果是java代码(非resttemplate)的写法是需要:

  1. 先把gzip流接住后还原;
  2. 再把流转成String;

这种是非常不正规的手法。

  • 如果说都是以gzip返回那么可以这么做;
  • 如果说一些以gzip流返回一些不是gzip流返回,这就很乱了对整体代码;

这种问题通常测试手法是发现不了的


这种问题,postman, jmeter, restclient都测不出来的,是因为postman, jmeter(4.0+), restclient都自带了“如果是gzip那么启用流解压后再造型成string“的功能了,因此只有在代码上一调用才调用的出来。

代码上可以规避的临时手法

resttemplate也是自带gzip流的,如何你用resttemplate是可以完全接住这种不正规的api返回的。

缺点是:resttemplate不据有微服役功能的,且改造需要很长时间,那么这将导致重大delay。

比较好的解决方法


因此对于这种做法我们可以使用以下手段一招解决

即把feignclient端的compression全部改成off,如下配置代码片段。即把compression.request.enabled和compression.response.enabled都改成false。即可。

feign:
   okhttp:
      enabled: true
   httpclient:
      enabled: false
      max-connections: 1000
      max-connections-per-route: 100
   compression:
      request:
         mime-types: text/xml,application/xml,application/json
         min-request-size: 2048
         enabled: false
      response:
         enabled: false

隐患

但这件事,会带来一个隐患,那就是:现在我们把这个参数关了,万一对方来一个超大的爆文一定会打爆微服务的组件,这块可以作为风险记录一下,因为按照正规的我们还是需要开启这个参数的,因此我们还是需要鼓励对接方能够正规化restful接口,正规化web服务器和应用服务器内的设置,如果碰到实在没办法了,那么我们就把feignclient端里这两个参数都开成false。

以上是关于微服务设计指导-feignclient的compression参数导致报文返回为gzip格式带来的坑的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 微服务中使用 FeignClient 报错 302

微服务|openfeign@FeignClient详解

DDD专栏7:DDD如何指导微服务设计实现

FeignClient注解及参数问题---SpringCloud微服务

微服务设计指导-微服务各层间应该如何调用

微服务设计指导-通过一个生产事故的具体例子来看微服务