SpringBoot开启Gzip接口报文压缩

背景

当我们一个接口响应报文比较大的时候,超过几兆甚至几十兆的情况下,减少响应体的报文大小是能有效减少响应时间的。

spring boot 配置

server:
  compression:
    ## 开启服务端的报文压缩
    enabled: true
    ## 只压缩响应类型为application/json的报文
    mime-types: application/json
    ## 触发压缩报文的最小响应体大小,默认2048字节(2KB)
    min-response-size: 2048

默认配置为:
image


光服务端配置好还不能保证服务端的响应报文被压缩,还有以下流程:

  1. 客户端(浏览器)的请求头(request header)需要带上参数字段 Accept-Encoding :gzip, deflate
    image

  2. 服务端的响应头(response header)返回参数字段 Content-Encoding : gzip
    image

  3. 客户端按照定好的格式进行报文解压工作。


  • 开启压缩前
    image

  • 开启压缩后
    image

开启feign请求响应报文压缩

配置

feign:
  compression:
    request:
      ## 开启feign请求压缩
      enabled: true
      ## 压缩报文类型
      mime-types: text/xml,application/xml,application/json
      ## 请求体大于2048字节则开启
      min-request-size: 2048
    response:
      ## 开启feign请求压缩
      enabled: true
      ## 使用gzip解码
      useGzipDecoder: true

默认配置为:
image

实现源码

  1. 如果开启feign响应压缩,则添加feign请求拦截器,并在请求头中添加字段 Accept-Encoding :gzip, deflate
    image

  2. 如果开启feign请求压缩,则添加feign请求拦截器,判断需要的响应体类型、请求体大小判断是否让响应体开启gzip报文压缩。
    image

避坑指南

当项目中开启了OkHttpClient时,会让feign.compression 配置失效。
image


我们项目中,有位已离职的同事写了这个配置,导致我们feign开启gzip一直失败、报错。

@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignOkHttpConfig {
    @Bean
    public okhttp3.OkHttpClient okHttpClient(){
        return new okhttp3.OkHttpClient.Builder()
                //设置连接超时
                .connectTimeout(10, TimeUnit.SECONDS)
                //设置读超时
                .readTimeout(10, TimeUnit.SECONDS)
                //设置写超时
                .writeTimeout(10,TimeUnit.SECONDS)
                //是否自动重连
                .retryOnConnectionFailure(true)
                .connectionPool(new ConnectionPool())
                //构建OkHttpClient对象
                .build();
    }
}

如果非得用okHttp,并支持feign请求压缩,则需要自己去尝试实现。

  1. 开启OkHttp,并关闭 httpClient
feign:
  httpclient:
    enabled: false
  okhttp:
    enabled: true
  1. okHttp有一套自己的玩法,
    image
    调试过程中,发现开启okHttp后,httpClient的代理失效了,因此我就不在往下探索了。
    可能需要自己配置 gzip encoder、gzip decoder,还有拦截器配置,感觉比较麻烦。

  2. 结论
    因此springboot项目中如果要开启gzip响应,最终还是不使用okHttp,减少接入复杂度、学习成本。
    即使okhttp的好处比较多:
    image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章