響應壓縮導致的接口請求response沒有響應體問題排查

目錄

    • 一、背景
    • 二、排查過程
    • 三、解決方法
    • 四、學習與思考-響應壓縮
      • (一)可能原因
      • (二)深入排查
      • (三)注意

一、背景

接口發布到測試環境,測試同學說沒有數據

二、排查過程

1、本地用相同的參數、相同的庫、相同的代碼分支,發現接口正常且有響應數據
2、懷疑是不是運維配置操作導致不是一個數據庫
3、排查所有可能用到的測試庫以及分支,發現接口還是正常的
4、實際去測試環境看接口請求響應,發現接口是200通的,但是response是空的,說明沒有響應體
5、測試環境:請求接口對應的sprinboot項目服務是通過nginx轉發的
最終懷疑是響應nginx攔截了

三、解決方法

  • springboot項目的yml配置文件如下
server:port: 55129servlet:context-path: /testcompression:mime-types: application/jsonenabled: true
  • 這里的true改為false,問題解決了

四、學習與思考-響應壓縮

(一)可能原因

  • 客戶端不支持壓縮:客戶端(像瀏覽器或者其他調用接口的應用程序)可能不支持服務器所采用的壓縮格式(通常是 gzip 或者
    deflate)。當客戶端接收到壓縮后的響應體時,無法正確對其進行解壓縮,從而造成無法解析響應數據。
  • 代理服務器問題:Nginx 作為代理服務器,可能沒有正確處理壓縮響應。例如,在轉發響應時,Nginx
    可能移除了與壓縮相關的請求頭或者響應頭,使得客戶端無法識別響應是經過壓縮的,進而無法正確解析。
  • 壓縮配置錯誤:Spring Boot
    的壓縮配置可能存在錯誤,比如壓縮算法不兼容、壓縮級別設置不合理等,導致壓縮后的響應體無法被客戶端正確解析。

(二)深入排查

1、檢查客戶端請求頭:要確保客戶端在請求頭中包含 Accept-Encoding 字段,并且其值為 gzip, deflate,以此表明客戶端支持這些壓縮格式。例如,在使用 HttpClient 發送請求時,可以這樣設置請求頭:

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;public class HttpClientExample {public static void main(String[] args) throws IOException, InterruptedException {HttpClient client = HttpClient.newBuilder().build();HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://your_domain_or_ip/bi/your_endpoint")).header("Accept-Encoding", "gzip, deflate").build();HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());}
}

2、配置 Nginx 支持壓縮:在 Nginx 配置文件中添加壓縮相關的配置,確保 Nginx 能夠正確處理壓縮響應。示例配置如下:

server {listen 80;server_name your_domain_or_ip;gzip on;gzip_types application/json text/html text/css application/javascript;location /bi {proxy_pass http://localhost:55129/bi;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Accept-Encoding ""; # 移除客戶端的Accept-Encoding頭proxy_pass_header Content-Encoding; # 傳遞響應的Content-Encoding頭}
}

3、檢查 Spring Boot 壓縮配置:確保 Spring Boot 的壓縮配置正確,例如 mime-types 設置是否包含了你希望壓縮的響應類型。

server:port: 55129servlet:context-path: /testcompression:mime-types: application/json, text/html, text/css, application/javascriptenabled: true

4、與后端服務器壓縮配置沖突:如果后端服務器(如 Spring Boot 應用)配置了響應壓縮,而 Nginx 沒有相應配置,可能會出現一些問題。例如,Nginx 可能會在轉發響應時移除或修改與壓縮相關的請求頭和響應頭,導致客戶端無法正確識別和處理壓縮后的數據。
移除或修改請求頭

后端服務器在收到客戶端請求時,會檢查請求頭中的Accept-Encoding字段,以確定客戶端支持的壓縮算法。如果客戶端支持gzip或deflate等壓縮算法,后端服務器會對響應數據進行壓縮,并在響應頭中添加Content-Encoding字段,告知客戶端響應數據的壓縮方式。
然而,Nginx
在轉發請求時,如果沒有配置處理壓縮相關的請求頭,可能會默認移除Accept-Encoding請求頭。這樣,后端服務器就無法得知客戶端支持的壓縮算法,可能會導致后端服務器對原本可以壓縮的數據不進行壓縮,或者采用客戶端不支持的壓縮算法進行壓縮。

移除或修改響應頭

后端服務器將壓縮后的響應數據發送給 Nginx,Nginx
在轉發響應時,如果沒有配置處理壓縮相關的響應頭,可能會移除Content-Encoding響應頭。客戶端接收響應時,由于沒有Content-Encoding頭信息,無法得知響應數據是經過壓縮的,會按照未壓縮的數據格式進行解析,導致解析錯誤。
另外,Nginx
也可能會修改Content-Length響應頭。因為壓縮后的數據長度通常會小于原始數據長度,后端服務器會根據壓縮后的數據長度設置Content-Length頭。但
Nginx
如果不了解壓縮情況,可能會錯誤地修改Content-Length頭為原始數據長度,導致客戶端在讀取響應數據時,按照錯誤的長度進行讀取,從而出現數據不完整或解析錯誤的情況。

  • 我們項目實際上就是nginx沒有配置響應壓縮,而springboot項目配置了響應壓縮,導致接口沒有響應體。

(三)注意

當前把 enabled 設為 false 雖然解決了問題,但這樣會使響應壓縮功能失效,在傳輸大文件或者大量數據時,會增加網絡帶寬的占用,降低數據傳輸的速度。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74027.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74027.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74027.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JVM中的運行時常量池詳解

運行時常量池&#xff08;Runtime Constant Pool&#xff09;是每一個類或接口的常量池&#xff08;Constant_Pool&#xff09;的運行時表示形式&#xff0c;它包括了若干種不同的常量&#xff1a;從編譯期可知的數值字面量到必須運行期解析后才能獲得的方法或字段引用。運行時…

C# MethodBase 類使用詳解

總目錄 前言 在C#編程中&#xff0c;反射&#xff08;Reflection&#xff09;是一種強大的機制&#xff0c;允許我們在運行時檢查和操作類型的成員。MethodBase 類是.NET框架中 System.Reflection 命名空間下的一個抽象類&#xff0c;它是所有方法( MethodInfo 和 Constructor…

【css酷炫效果】純CSS實現3D翻轉卡片動畫

【css酷炫效果】純CSS實現3D翻轉卡片動畫 緣創作背景html結構css樣式完整代碼效果圖 想直接拿走的老板&#xff0c;鏈接放在這里&#xff1a;https://download.csdn.net/download/u011561335/90490472 緣 創作隨緣&#xff0c;不定時更新。 創作背景 剛看到csdn出活動了&am…

Flask多參數模版使用

需要建立目錄templates&#xff1b; 把建好的html文件放到templates目錄里面&#xff1b; 約定好參數名字&#xff0c;單個名字可以直接使用&#xff1b;多參數使用字典傳遞&#xff1b; 樣例&#xff1a; from flask import render_template # 模板 (Templates) #Flask 使用…

SVN簡明教程——下載安裝使用

SVN教程目錄 一、開發中的實際問題二、簡介2.1 版本控制2.2 Subversion2.3 Subversion的優良特性2.4 工作原理2.5 SVN基本操作 三、Subversion的安裝與配置1. 服務器端程序版本2. 下載源碼包3. 下載二進制安裝包4. 安裝5. 配置版本庫① 為什么要配置版本庫&#xff1f;② 創建目…

OpenCV圖像拼接(1)概述

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 此圖說明了在Stitcher類中實現的拼接模塊流程。使用該類&#xff0c;可以配置/移除某些步驟&#xff0c;即根據特定需求調整拼接流程。流程中的所…

Ubuntu20.04安裝Nvidia顯卡驅動

Ubuntu20.04安裝Nvidia顯卡驅動 安裝環境為Dell R540服務器 官網下載Nvidia顯卡驅動 https://www.nvidia.cn/geforce/drivers/ 安裝顯卡驅動 chmod x NVIDIA-Linux-x86_64-470.63.01.run sudo ./NVIDIA-Linux-x86_64-470.63.01.run 遇到nouveau報錯 lsmod查看nouveau驅動…

互聯網it常用抓包工具說明

一、引言 在互聯網 IT 領域&#xff0c;無論是網絡故障排查、安全檢測&#xff0c;還是開發調試&#xff0c;抓包工具都發揮著舉足輕重的作用。 當網絡出現故障&#xff0c;比如網頁加載緩慢、應用無法連接服務器時&#xff0c;抓包工具可以幫助我們捕獲網絡數據包&#xff0…

Linux 音頻驅動 WM8960 音頻 DAC IC 音樂播放與錄音

這些先引出一個內容&#xff0c;是 Linux 內核的音頻系統&#xff0c;ALSA&#xff0c;提供了對聲卡的低級訪問&#xff0c;支持 PCM&#xff0c;播放/錄音、混音、MIDI 處理等功能。它取代了舊的 OSS&#xff0c;并提供更強大的功能和更好的硬件支持。 ALSA 主要特點&#xf…

k8s中的組件

1.namespace Namespace 用于將集群資源劃分為不同的邏輯組&#xff0c;方便管理和隔離 kubectl get namespace 查看所有邏輯組 kubectl describe namespace <namespace-name> 查看某個邏輯組信息詳情 kubectl create namespace ... 創建邏輯組 kubectl delete names…

OpenHarmony 開源鴻蒙北向開發——3.配置SDK

安裝、配置完成之后我們就要配置SDK。 我們創建工程后&#xff0c;點擊右上角設置 進入設置 進入OpenHarmony SDK&#xff0c;選擇編輯 這里配置一下SDK安裝位置 點擊完成 這里我們API版本勾選第一個即可 確認安裝 勾選接受 這里要等一會 安裝完成后&#xff0c;點擊完成

5.2《生活中的透鏡》——5.3《凸透鏡成像規律》講后再上

教會什么:照相機、投影儀、放大鏡的原理 培養什么:(再說) 課標: (二)運動和相互作用 2.3 聲和光 2.3.5了解凸透鏡成像規律的應用。 例7 了解凸透鏡成像規律在放大鏡、照相機中的應用。 一、導入 提問:生活中有哪些透鏡?(放大鏡、照相機、投影儀/幻燈機) ——直接提出…

怎么用LoRA的低秩結構近似Fisher矩陣

怎么用LoRA的低秩結構近似Fisher矩陣 目錄 怎么用LoRA的低秩結構近似Fisher矩陣**1. Fisher矩陣的內存挑戰****2. LoRA的低秩結構與Fisher近似****3. 具體實現步驟****4. 示例說明****5. 有效性分析****6. 擴展與優化****總結**在LoRA(低秩適應)中,通過低秩結構近似Fisher矩…

C#通過API接口返回流式響應內容---SignalR方式

1、背景 在上兩篇《C#通過API接口返回流式響應內容—分塊編碼方式》和《C#通過API接口返回流式響應內容—SSE方式》實現了流式響應的內容。 上面的這兩個主要是通過HTTP的一些功能&#xff0c;除了這些之外&#xff0c;還有WebSocket的方式。C#中的WebSocket的有比較多的方案&…

Redis 跳表原理詳解

一、引言 在 Redis 中&#xff0c;有序集合&#xff08;Sorted Set&#xff09;是一種非常重要的數據結構&#xff0c;它可以實現元素的有序存儲和高效查找。而實現有序集合的底層數據結構之一就是跳表&#xff08;Skip List&#xff09;。跳表是一種隨機化的數據結構&#xff…

識別并脫敏上傳到deepseek/chatgpt的文本文件中的身份證/手機號

本文將介紹一種簡單高效的方法解決用戶在上傳文件到DeepSeek、ChatGPT,文心一言,AI等大語言模型平臺過程中的身份證號以及手機號等敏感數據識別和脫敏問題。 DeepSeek、ChatGPT,Qwen,Claude等AI平臺工具快速的被接受和使用,用戶每天上傳的文本數據中潛藏著大量敏感信息,…

Spring 如何創建 Bean 實例的?

Spring 創建 Bean 實例的過程主要由 BeanFactory 接口及其實現類&#xff08;通常是 AbstractBeanFactory 的 doGetBean 方法和 DefaultListableBeanFactory 的 preInstantiateSingletons 方法&#xff09;負責。這個過程涉及多個步驟&#xff0c;包括 Bean 定義的解析、依賴的…

第六:go 操作 redis-go

Redis 在項目開發中redis的使用也比較頻繁&#xff0c;本文介紹了Go語言中go-redis庫的基本使用。 Redis介紹 Redis是一個開源的內存數據庫&#xff0c;Redis提供了多種不同類型的數據結構&#xff0c;很多業務場景下的問題都可以很自然地映射到這些數據結構上。除此之外&am…

【RabbitMQ】RabbitMQ如何保證消息不丟失?

為了保證消息不丟失&#xff0c;需要在生產者、RabbitMQ本身和消費者三個環節采取相應措施。 1.生產者端&#xff1a;確保消息發送成功 1.1開啟消息確認機制(Publisher Confirms) 原理&#xff1a; 生產者發送消息后&#xff0c;RabbitMQ會返回一個確認(ACK),表示消息已成功…

fastapi+angular外賣系統

說明&#xff1a; fastapiangular外賣系統 1.美食分類&#xff08;粥&#xff0c;粉&#xff0c;面&#xff0c;炸雞&#xff0c;炒菜&#xff0c;西餐&#xff0c;奶茶等等&#xff09; 2.商家列表 &#xff08;kfc&#xff0c;蘭州拉面&#xff0c;湘菜館&#xff0c;早餐店…