結論先講

檔案上傳是 I/O-bound 操作,但 bcrypt 仍然出現在 5 個框架的瓶頸標記中。 因為測試流程包含用戶認證。Spring Boot 和 Go 並列第一(健康 VU 1,000),NestJS 第三(500)。Express-TS 因為沒有 reverse proxy 做 connection buffering,健康 VU 直接是 0——不是因為處理慢,是因為連線被打穿。


排名

#框架健康 VUMax RPS瓶頸CRUD混合
1Spring Boot1,000251CPU 密集8th1st
2Go1,000281CPU 密集1st2nd
3NestJS500154DB 查詢慢4th6th
4Django50061Bcrypt9th5th
5.NET Core10037Bcrypt2nd4th
6Express-JS100186連線數上限5th-
7FastAPI1030Bcrypt6th3rd
8Laravel109Bcrypt7th-
9Express-TS0204連線數上限3rd-

三場排名走勢

         CRUD     混合     上傳
Go       1st  →   2nd  →   2nd    ← 穩定
Spring   8th  →   1st  →   1st    ← 非 CRUD 場景王者
NestJS   4th  →   6th  →   3rd    ← 上傳場景亮眼
FastAPI  6th  →   3rd  →   7th    ← 上傳場景暴跌
Express  3rd  →   -    →   9th    ← 連線數問題

Express-TS 的矛盾數字

Express-TS 健康 VU = 0(最後一名),但 Max RPS = 204(第三高)。怎麼回事?

「連線數上限」瓶頸——Express.js 沒有 connection buffering。大量併發上傳的連線直接灌到 Node.js 的 event loop,超出處理能力時 error rate 立刻飆升。但在 error 發生前的短暫時間內處理速度很快(204 RPS)。

對比 Laravel 前面有 Nginx 做 connection buffering(第 33 篇),Spring Boot 有 Tomcat 的 acceptCount——Express.js 什麼保護都沒有。

教訓:Express.js 上生產一定要在前面加 Nginx。(呼應 Infra 篇 的建議)

FastAPI 從混合第 3 跌到上傳第 7

FastAPI 在混合場景排第 3(健康 VU 100),但在檔案上傳場景跌到第 7(健康 VU 僅 10)。

問題在 python-multipart 的記憶體管理——多個 1MB 檔案同時上傳時 uvicorn worker 記憶體飆升。在 2 GB Docker 限制下很快就到頂。

NestJS 上傳場景意外亮眼

NestJS 從混合場景的第 6 升到上傳的第 3(健康 VU 500, 154 RPS)。Multer 是 Node.js 生態中最成熟的檔案上傳 middleware,加上 PM2 cluster 分攤了記憶體壓力。


Streaming vs Buffering

框架處理上傳檔案的方式分兩派:

方式框架記憶體使用吞吐量
StreamingGo (io.Reader)低且穩定
Buffering + 暫存檔Spring Boot, Django中,穩定中高
記憶體 BufferingFastAPI, Laravel高,不穩定
Multer(混合)NestJS, Express

Go 的 io.Reader 介面讓上傳天然是 streaming 的——檔案邊收邊寫,不需要全部讀進 RAM。Spring Boot 的 Servlet multipart 先寫暫存檔再處理,多了一次 disk I/O 但記憶體穩定。

如果你的應用需要處理大量檔案上傳,Go 的 streaming 模型最佳。


三場壓測的綜合觀察

框架CRUD混合上傳一句話
Go1st2nd2nd最穩定——不是每次第一但從不墊底
Spring Boot8th1st1st非 CRUD 場景王者,JVM 在讀取/I/O 密集下無敵
NestJS4th6th3rd波動但整體中上
FastAPI6th3rd7th混合場景好,上傳場景差
Django9th5th4th穩定上升,給足資源表現不差
.NET Core2nd4th5th穩定下降,BCrypt.Net 是軟肋

接下來等 WS+SSE、Queue、Redis On/Off、Batch Upload、Cold Start 的數據在平台上整理好,就能繼續寫剩下的 B2E 文章。


下一篇

WebSocket 與 SSE 壓測:所有框架都能撐,差異不在這裡 — HTTP request-response 看完了,接下來看持久連線。WS 和 SSE 的結果出乎意料地無聊——因為所有框架都能撐。



B2E 五場壓測回顧

到這裡,B2E 的主要壓測場景都跑完了。回顧五場的核心發現:

場景核心發現詳細篇章
CRUDbcrypt 是所有框架的共同天花板[[micro-service/09-crud-overview|#9-14]]
混合場景Spring Boot 從第 8 翻盤到第 1[[micro-service/24-mixed-overview|#24]]
檔案上傳Streaming vs Buffering 決定天花板本篇
WS/SSE所有框架都能撐,不是差異點[[micro-service/26-websocket-sse|#26]]
Queue/Redis/Cold Start差異在生態不在速度[[micro-service/27-queue-redis-coldstart|#27]]

跨場景的三個結論:

  1. 沒有「最好的框架」——Go CRUD 最穩、Spring Boot 混合最強、Express-TS 生態最大
  2. 免費午餐比換框架效果大([[micro-service/21-infra-free-lunch|#21]]:Redis + keepalive + multi-worker = 13 倍)
  3. 選框架看場景 + 團隊 + 預算([[micro-service/23-cross-layer-capacity|#23]]:容量規劃表)

本系列文章

完整 68 篇目錄見 系列首頁

← 上一篇:混合場景壓測:Spring Boot 從倒數第二變第一名 → 下一篇:WebSocket 與 SSE 壓測:所有框架都能撐,差異不在這裡