【要約】FastAPI async def ハンドラ内の subprocess.run でWebUI全体がフリーズした障害と修正 [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
開発者がFastAPIアプリの開発中に、特定のリクエストでWebUI全体がフリーズする問題に直面した。単一の重い処理が、システム全体の応答性を奪う事態となった。
- ・
async def内で同期的なsubprocess.runを実行した。 - ・イベントループが停止し、全リクエストの受付が不能となった。
- ・CPU使用率は低いまま、ネットワークの受信キューにリクエストが滞留した。
// Approach
エンジニアは、
ssや/proc/<pid>/wchanによる診断を経て、ハンドラとプロセス管理を修正した。ブロッキングを回避し、プロセスのライフサイクルを厳格に制御する手法を採用した。- ・
async defをdefへ変更し、Starletteのスレッドプールを利用した。 - ・
subprocess.runをsubprocess.Popenへ変更した。 - ・
start_new_session=Trueにより、プロセスグループ単位での強制終了を実現した。
// Result
修正の結果、重い処理を実行中であっても他のリクエストを並行して処理できるようになった。システムの可用性とリソース管理の両面で改善が見られた。
- ・WebUIの全ページが、生成処理中も正常に操作可能となった。
- ・タイムアウト時に孫プロセスを含めて確実にクリーンアップできるようになった。
- ・リソースの滞留を防ぎ、システムの可用性が向上した。
Senior Engineer Insight
> 「async = 高速」という誤解が招いた典型的な設計ミスである。FastAPIにおいて、awaitできない同期I/Oをasync defに閉じ込める行為は、システムの可用性を破壊する。また、外部プロセス管理において孫プロセスの生存を考慮しない設計は、リソース枯渇を招く。カーネルレベルの挙動を理解し、プロセスライフサイクルを厳格に制御する姿勢が不可欠である。