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

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