流式輸出阻塞原因及解決辦法

流式輸出不懂可看這篇文章:流式輸出:概念、技巧與常見問題

正常情況,如下代碼所示:

    async def event_generator():# 先輸出數字1yield "data: 1\n\n"# 然后每隔2秒輸出數字2,共輸出10次for i in range(10):await asyncio.sleep(2)  # 等待2秒yield "data: 2\n\n"return StreamingResponse(event_generator(),media_type="text/event-stream",)

一、網絡緩存

在FastAPI中實現Server-Sent Events (SSE)流式響應時,經常遇到響應數據不是實時發送給客戶端,而是累積到一定程度后一次性發送的問題。這主要由以下幾個原因造成:

  • 網絡層緩沖機制:網絡協議棧為了提高傳輸效率,會將小的數據包進行緩沖合并,這種現象稱為Nagle算法或TCP延遲確認。
  • 應用層緩沖:
    Web服務器(如uvicorn)和ASGI應用本身可能對響應內容進行緩沖
    Python的異步框架在處理異步生成器時,可能會將多個yield值緩存起來批量處理
  • 事件循環調度:
    在同一個異步函數中連續調用yield時,事件循環可能不會立即切換到發送數據的協程
    需要顯式地讓出控制權,使事件循環有機會處理數據發送

解決方法:

  • 事件循環控制權讓出:
    await asyncio.sleep(0)會讓當前協程暫停執行,并將控制權交還給事件循環
    事件循環會處理其他待處理的任務,包括將已生成的數據發送給客戶端

  • 打破緩沖機制:
    通過在每次yield后添加await asyncio.sleep(0),強制中斷當前協程的連續執行
    這給底層傳輸機制一個機會來刷新緩沖區并發送數據

    async def event_generator():# 先輸出數字1yield "data: 1\n\n"# 如果是下面這種就會產生阻塞,需要使用 await asyncio.sleep(0)for event in coze.chat.stream(bot_id=bot_id,user_id=user_id,additional_messages=user_messages,):if event.event == ChatEventType.CONVERSATION_MESSAGE_DELTA:yield f"data: {event.message.content}\n\n"# 強制刷新緩沖區,確保數據立即發送await asyncio.sleep(0)return StreamingResponse(event_generator(),media_type="text/event-stream",)

二、Nginx 緩存

Nginx 作為反向代理時,流式輸出出現問題是很常見的問題。Nginx 默認會緩沖后端的響應,這會導致流式傳輸無法正常工作,主要原因包括:

  • Nginx默認啟用緩沖,會等待后端響應完成后再轉發給客戶端
  • HTTP/1.0的連接行為可能中斷流式傳輸
  • 超時設置過短導致連接被提前關閉

第一步:在返回方法處,添加 headers 參數,如下

return StreamingResponse(generate_stream(agent_id, BOT_ID, file_id, content, background_tasks),media_type="text/event-stream",headers={"Cache-Control": "no-cache","Connection": "keep-alive","X-Accel-Buffering": "no"  # 禁用Nginx緩沖})

第二步:如果第一步未解決,則修改Nginx配置文件,添加關鍵配置下面幾行

    location /api/ {proxy_pass http://127.0.0.1:8051/;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_buffering off;proxy_cache off;proxy_read_timeout 86400s;proxy_send_timeout 86400s;}

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

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

相關文章

linux系統----Ansible中的playbook簡單應用

目錄 Playbooks中tasks語法使用 1、file 創建文件:touch 創建目錄:directory 2、lineinfile 修改文件某一行文本 3、replace 根據正則表達式替換文件內容(指定換字符串) 5、template/copy 模板作用類似于copy&#xff0…

bmcweb工作流程

在openbmc中,bmcweb是一個web服務程序,類似于lighttpd,提供web服務。本文將簡單介紹這個服務進程的執行流程。 bmcweb的入口函數main(). main() -> run() run()先注冊routes,最后調用app.run(). 第一個注冊的route為crow::webassets:requestRoutes(). crow::webasse…

傘狀Meta分析重構癌癥幸存者照護指南:從矛盾證據到精準決策

還記得你第一次做出Meta分析時的成就感嗎?那種從海量文獻中抽絲剝繭,最終得出可靠結論的感覺,簡直不要太爽!但是,時代在進步,科研在卷動,Meta分析也有它的"升級版"——傘狀Meta分析&a…

IOMMU Client設備DMA配置過程分析(九)

1.設備樹 cp0_pcie0是一個PCIe RC控制器,使用SMMU將PCIe設備的IOVA轉換成物理地址,使用iommu-map-mask和iommu-map定義PCIe設備使用的Stream ID。設備樹定義如下所示。 [arch/arm64/boot/dts/marvell/armada-ap80x.dtsi] smmu: iommu100000 {compatibl…

使用node-cron實現Node.js定時任務

1. 簡介 node-cron 是一個輕量級的Node.js庫,用于在指定時間或間隔執行任務。它是Unix系統cron工具的JavaScript實現,適用于需要定時執行腳本的場景(如數據備份、定期爬蟲等)。 2. 安裝 npm install node-cron # 或 yarn add node…

前綴和-525.連續數組-力扣(LeetCode)

一、題目解析1、只包含0、1的二進制數組2、找到含有相同數量的0和1,并返回其子數組長度二、算法原理解法1:暴力枚舉 時間復雜度O(N^2)解法2:前綴和哈希表對于統計子數組中的0和1的數量有點困難,我們可以將其轉化一下轉化&#xff…

汽車電子控制系統開發的整體安全理念

1. 摘要在汽車制造商和一級供應商避免責任的背景下,公認的技術規則作為法律要求的標準具有重要的實際意義。道路車輛電子控制單元的安全性目前主要通過 ISO 26262 的要求和流程來保障。特別是隨著道路交通自動化程度的不斷提高以及現代車輛隨之而來的復雜性&#xf…

IDEA重新安裝常用設置

IDEA重新安裝常用設置 展示固定導航欄 項目構建和運行操作委托給maven 參考:IDEA build委托到Maven build

微服務的編程測評系統9-競賽新增-競賽編輯

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄前言1. 競賽新增1.1 競賽基本信息增加-后端開發1.2 競賽新增題目-后端1.3 競賽基本信息-前端1.4 競賽新增題目-前端2. 競賽編輯2.1 競賽詳情-后端2.2 競賽詳情-前端2…

《零基礎入門AI:線性回歸進階(梯度下降算法詳解)》

在上一篇博客中,我們學習了線性回歸的基本概念、損失函數(如MSE)以及最小二乘法。最小二乘法通過求解解析解(直接計算出最優參數)的方式得到線性回歸模型,但它有一個明顯的局限:當特征數量很多時…

基于C語言實現的KV存儲引擎(一)

基于C語言實現的KV存儲引擎項目簡介整體架構網絡模塊的實現recatorproactorNtyco項目簡介 本文主要是基于 C 語言來實現一個簡單的 KV 存儲架構,目的就是將網絡模塊跟實際開發結合起來。 首先我們知道對于數據的存儲可以分為兩種方式,一種是在內存中進…

c++和python聯合編程示例

安裝 C與 Python 綁定工具 pip install pybind11這其實相當于使用 python 安裝了一個 c的庫 pybind11,這個庫只由頭文件構成, 支持基礎數據類型傳遞以及 python 的 numpy 和 c的 eigen 庫之間的自動轉換。 編寫 CMakeList.txt cmake_minimum_required(VERSION 3.14)…

【OD機試題解法筆記】貪心歌手

題目描述 一個歌手準備從A城去B城參加演出。 按照合同,他必須在 T 天內趕到歌手途經 N 座城市歌手不能往回走每兩座城市之間需要的天數都可以提前獲知。歌手在每座城市都可以在路邊賣唱賺錢。 經過調研,歌手提前獲知了每座城市賣唱的收入預期&#xff1a…

AI: 告別過時信息, 用RAG和一份PDF 為LLM打造一個隨需更新的“外腦”

嘿,各位技術同學!今天,我們來聊一個大家在使用大語言模型(LLM)時都會遇到的痛點:知識過時。 無論是像我一樣,用 Gemini Pro 學習日新月異的以太坊,還是希望它能精確掌握某個特定工具…

深度學習(魚書)day08--誤差反向傳播(后三節)

深度學習(魚書)day08–誤差反向傳播(后三節)一、激活函數層的實現 這里,我們把構成神經網絡的層實現為一個類。先來實現激活函數的ReLU層和Sigmoid層。ReLU層 激活函數ReLU(Rectified Linear Unit&#xff…

C# 中生成隨機數的常用方法

1. 使用 Random 類(簡單場景) 2. 使用 RandomNumberGenerator 類(安全場景) 3. 生成指定精度的隨機小數 C# 中生成隨機數的常用方法: 隨機數類型實現方式示例代碼特點與適用場景隨機整數(無范圍&#xf…

Flink 算子鏈設計和源代碼實現

1、JobGraph (JobManager) JobGraph 生成時,通過 ChainingStrategy 連接算子,最終在 Task 中生成 ChainedDriver 鏈表。StreamingJobGraphGeneratorcreateJobGraph() 構建jobGrapch 包含 JobVertex setChaining() 構建算子鏈isCha…

對接八大應用渠道

背景最近公司想把游戲包上到各個渠道上,因此需要對接各種渠道,渠道如下,oppo、vivo、華為、小米、應用寶、taptap、榮耀、三星等應用渠道 主要就是對接登錄、支付接口(后續不知道會不會有其他的)&#x…

學習:入門uniapp Vue3組合式API版本(17)

42.打包發行微信小程序的上線全流程 域名 配置 發行 綁定手機號 上傳 提交后等待,上傳 43.打包H5并發布上線到unicloud的前端頁面托管 完善配置 unicloud 手機號實名信息不一致:請確保手機號的實名信息與開發者姓名、身份證號一致,請前往開…

SOLIDWORKS材料明細表設置,屬于自己的BOM表模板

上一期我們了解了如何在SOLIDWORKS工程圖中添加材料明細表?接下來,我們將進行對SOLIDWORKS材料明細表的設置、查看縮略圖、模板保存的深度講解。01 材料明細表設置菜單欄生成表格后左側菜單欄會顯示關于材料明細表的相關設置信息。我們先了解一下菜單欄設置詳情&am…