微服务设计指导-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)的写法是需要:
- 先把gzip流接住后还原;
- 再把流转成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