Spring Boot SseEmitter 重復請求問題深度分析與解決方案

1. 前言

在使用 Spring Boot 開發流式接口(Server-Sent Events)時,我們遇到了一個令人困惑的問題:每次 SseEmitter 完成后,都會觸發第二次請求,導致重復請求檢測機制誤報。本文將詳細記錄問題的發現、分析過程以及最終的解決方案。

2. 系統架構背景

2.1 請求處理架構

我們的系統采用了標準的 Spring Boot 微服務架構,其中包含一個關鍵的請求攔截器組件:

@Component
@Slf4j
public class RequestHandlerInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 1. API 簽名校驗// 2. 重復請求過濾// 3. 用戶權限驗證// 4. 請求日志記錄return true;}
}

RequestHandlerInterceptor 的主要職責:

  • API 簽名校驗:驗證請求的數字簽名,確保請求的完整性和來源可信
  • 重復請求過濾:基于 Redis 緩存的防重復提交機制,防止用戶誤操作
  • 用戶權限驗證:檢查用戶登錄狀態和訪問權限
  • 請求日志記錄:記錄關鍵請求信息用于審計和問題排查

2.2 系統部署架構

客戶端 → Nginx → Spring Boot 微服務 → RequestHandlerInterceptor → Controller

3. 問題現象

3.1 初始癥狀

在我們的導出服務中,使用 SseEmitter 實現流式 PDF 生成功能時,RequestHandlerInterceptor 的 preHandle 方法出現了異常的重復調用現象

@PostMapping("/monthReport/insurance/v3/pdf/stream")
public SseEmitter reportInsurancePDFV3Stream(@RequestBody ReportInsuranceV3StreamDTO dto) {// SseEmitter 實現
}

RequestHandlerInterceptor 日志顯示的異常行為:

2025-07-07 17:00:33.245  INFO  [XNIO-1 task-9]  RequestHandlerInterceptor.preHandle() - 第一次調用
2025-07-07 17:00:33.448  INFO  [XNIO-1 task-9]  === reportInsurancePDFV3Stream START ===
2025-07-07 17:01:21.978  INFO  [async-IO-1]    === CALLING emitter.complete() ===
2025-07-07 17:01:22.046  INFO  [XNIO-1 task-13] RequestHandlerInterceptor.preHandle() - 第二次調用!
2025-07-07 17:01:22.054  WARN  [XNIO-1 task-13] 重復請求檢測觸發,客戶端信息:...
2025-07-07 17:01:22.087  INFO  [XNIO-1 task-14] === SseEmitter COMPLETION ===

3.2 關鍵發現

  1. 攔截器重復調用RequestHandlerInterceptor.preHandle() 方法被調用了兩次
  2. 時間差異emitter.complete() 調用和第二次攔截器調用之間有明顯的時間間隔
  3. 線程差異:第二次攔截器調用在不同的線程中執行
  4. 重復檢測觸發:第二次調用被重復請求檢測機制攔截,導致異常拋出

4. 問題分析歷程

4.1 第一階段:排除外部因素

面對這個奇怪的現象,我們首先懷疑是外部因素導致的重復請求。

4.1.1 排除前端重試機制

最初懷疑是前端 EventSource 存在重試邏輯:

eventSource.onerror = function(event) {// 可能的重試邏輯startExport();
};

驗證方法:使用 curl 直接測試

為了排除前端重復調用的可能性,我們繞過前端,直接使用 curl 命令測試接口:

curl -X POST "http://localhost:8080/api/stream" \-H "Content-Type: application/json" \-H "Authorization: Bearer eyJhbI1NiIsInR5cCI6IkpXVCJ9..." \-H "X-Ca-Nonce: 1234567890" \-d '{"patientId":"176900913670569984","startTime":"2023-07-01","endTime":"2023-07-31"}'

結果:問題依然存在!

即使繞過前端,直接使用 curl 訪問,RequestHandlerInterceptor.preHandle() 仍然被調用了兩次,這證明問題不在前端。

4.1.2 排除 Nginx 配置問題

接下來懷疑是 Nginx 的配置或重試機制導致的:

  • Nginx 的 proxy_retry 配置
  • Nginx 的超時重試機制
  • Nginx 的負載均衡重試

驗證方法:繞過 Nginx 直接訪問微服務

我們直接訪問微服務端口,完全繞過 Nginx:

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

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

相關文章

心路歷程-三個了解敲開linux的大門

學習前都愛嘮叨一番: 了解一下:互聯網的發展是離不開服務器的,而服務器的系統主流的還是Linux;這個是有數據進行支撐的;這個只是作為了解而已,我們并不買課,也不做什么買賣的行為,僅…

關于“雙指針法“的總結

筆者這些天終于達成了只狼的全成就,甚是歡喜。然而樂極生悲,最近做了些算法題,竟沒有一道靠自己做出來。感覺算法題常常用到“雙指針法”呢……為什么到現在我還是做不出來這些算法題……今天就來試著總結一下它的使用場景吧。快慢指針法又名…

基于51單片機的智能吊燈

基于 51 單片機的智能吊燈設計與實現論文簡綱一、引言1.1 研究背景與意義闡述傳統照明設備在節能性、智能化方面的不足,結合智能家居產業發展趨勢,說明設計基于 51 單片機的智能吊燈對提升生活便利性、降低能耗的現實意義。1.2 國內外研究現狀簡要介紹當…

CF每日三題(1500-1700)

1792C 逆向思維1036D 前綴和尺取1598D 組合數學取三元組 將二元組放在坐標系中更好找到規律 1792C 思維 1500 參考題解 正難則反 注意是對一個排列進行操作,最后還原成1,2,…,n 每次選兩個數字很難想,反著想就是把1-n的排列變成所給數組的逆操作&#x…

Boost搜索引擎項目(詳細思路版)

目錄 項目相關背景 搜索引擎原理技術棧和項目環境 導入數據到自己的本地 數據去標簽與數據清洗模塊 Enumfile(src_path, &file_list)遞歸式寫入 Parsehtml(file_list, &results)去標簽 bool Parsetitle(const string& file, string* title)拆分標題 bool Pa…

AI產品經理面試寶典第69天:大模型穩定性評估與AI倫理挑戰面試題全解析

1. AI倫理與技術挑戰 1.1 問:你認為AI的最大挑戰是什么? 答:AI面臨的最大挑戰是算法偏見與模型黑箱問題。具體表現為: 數據偏見放大:訓練數據中隱含的性別、種族等偏見會被模型繼承,如招聘算法中的性別歧視案例 決策透明性缺失:深度學習模型的可解釋性不足,醫療診斷場…

【build】RDK構建系統v0.1 (持續更新。。。。)

一、 項目概述RDK構建系統是一個用于構建和定制嵌入式系統的自動化工具,通過簡單的命令行操作,您可以完成從下載依賴包、定制根文件系統、構建內核到打包鏡像的完整流程。該系統采用模塊化設計,提供了豐富的配置選項,適用于不同的…

關于RSA和AES加密

RSA非對稱加密 非對稱加密不能傳輸大數據量,但比對稱加密要安全,所以傳輸密碼一般就是用的非對稱加密 接口拿到RSA公鑰然后再加密之后傳給后端就好了 let crypt new JSEncrypt(); crypt.setPublicKey(res.message); // console.log(加密前:, data); let…

云蝠智能VoiceAgent:AI賦能售后服務場景的創新實踐

引言:售后服務數字化轉型的必然趨勢在數字經濟時代,售后服務已成為企業核心競爭力的重要組成部分。據統計,優質的售后服務能夠提升客戶留存率高達67%,同時降低客戶獲取成本約30%。然而,傳統售后服務模式面臨著人力成本…

C#控制臺輸入(Read()、ReadKey()和ReadLine())

下面我們來詳細講解 C# 中三種控制臺輸入方法:Console.Read()、Console.ReadKey() 和 Console.ReadLine() 的區別、原理、使用場景,并配上清晰的代碼例子和運行結果說明。? 一、三者的根本區別(一句話總結)方法返回值讀取方式是否…

Windows的Roaming文件夾的作用和Local/LocalLow的區別

📁 Roaming 文件夾的核心意義? 什么是“漫游”(Roaming)?跨設備同步:當用戶登錄到同一域內的不同 Windows 設備(如公司或學校的辦公電腦)時,Roaming 文件夾中的數據會自動通過網絡同…

【Java Web 快速入門】十一、Spring Boot 原理

目錄Spring Boot 原理配置優先級Bean 管理獲取 BeanBean 的作用域第三方 BeanSpring Boot 底層原理起步依賴自動配置核心原理實例說明例 1:自定義一個 “日志 starter”例 2:SpringBoot 自帶的 spring-boot-starter-web關鍵總結Spring Boot 原理 配置優…

基于Redisson的分布式鎖原理深度解析與優化實踐

基于Redisson的分布式鎖原理深度解析與優化實踐 分布式環境下,鎖的實現至關重要。本文將從技術背景與應用場景出發,結合核心原理、關鍵源碼、實際示例,深入剖析Redisson分布式鎖的實現機制,并給出性能優化建議,幫助后端…

室外 3DVG 基準

室外 3DVG基準(按重要性與被引用頻率) Talk2Car / Talk2Car-3D (2019 / 衍生) — 對象 referral(駕駛場景) 說明:最早的自然語言 → 駕駛場景對象引用數據集之一(原 Talk2Car 是以 nuScenes 為底并提供自然…

Jenkins安裝部署(Win11)和常見配置鏡像加速

一、安裝前準備 本文使用的Jenkins Windows一鍵安裝包,JDK事先配置好環境變量,Jenkins版本: Jenkins下載地址:jenkins一鍵安裝包v2-479-1.msi資源-CSDN下載 二、Jenkins安裝部署 1、下載Jenkins ,點擊下一步下一步…

Windows MCP.Net:革命性的 .NET Windows 桌面自動化 MCP 服務器

📋 目錄 項目概述 核心技術架構 功能特性詳解 技術實現亮點 安裝與配置 實戰應用場景 代碼示例與API詳解 性能優化與最佳實踐 未來發展規劃 總結 項目概述 在人工智能快速發展的今天,AI 助手與操作系統的深度集成成為了一個重要趨勢。Window…

Java ArrayList的介紹及用法

十分想念順店雜可。。。ArrayList 是 Java 集合框架中最常用的類之一,實現了 List 接口,底層基于動態數組實現,支持動態擴容,相比普通數組更靈活。以下是其詳細介紹及用法:一、核心特性動態大小:無需預先指…

Docker 命令大全及使用場景總結

一、容器生命周期管理1. 創建并運行容器docker run [選項] 鏡像名 [命令]常用選項:-d:后臺運行(detached)-it:交互式終端(如 -it ubuntu bash)--name:指定容器名稱-p 主機端口:容器端…

簡單的 HTTPS 學習

簡單的 HTTPS 學習 1. 需求 現在使用的服務是HTTP調用形式,服務可能會有調用外圍https形式的服務,簡單了解了一下,然后寫了一個簡單的例子進行記錄。 HTTP(超文本傳輸協議) 是一種用于傳輸超文本的應用層協議&#…

[系統架構設計師]系統質量屬性與架構評估(八)

[系統架構設計師]系統質量屬性與架構評估(八) 一.軟件系統質量屬性 1.基本概念 軟件系統質量屬性:可測量或可測試的屬性 開發期質量屬性,運行期質量屬性面向架構評估的質量屬性:1.可用性: 提升策略 錯誤檢測…