這是長篇深入探討。如需更快、略讀的版本,請參閱 同伴部落格文章.

1. 簡介:習慣堆疊與實際工作負載
成熟組織中的技術選擇很少會失敗,因為沒有人閱讀基準部落格文章。他們失敗是因為 過程 選擇是很弱的:大聲的高階工程師的偏好,充滿一種語言的招聘渠道,或者會議上令人印象深刻的演示。與此同時,該產品混合了對延遲敏感的 API、批次協調、NGINX 中的邊緣身份驗證、內部 CLI 以及偶爾出現的無伺服器峰值。一個執行時間不可能對所有這些形狀都是最佳的。
這篇文章解釋了 多語言基準 — 實時比較儀表板和開放的 工作流程示例/基準 背後的安全帶——作為 決策框架,不是粉絲排行榜。目標是您可以附加到架構決策記錄 (ADR) 的證據:相同的端點、相同的負載生成器、相同的容器佈局、多種語言。
我不會在散文中發明吞吐量數字。當您執行該工具時,儀表板會顯示該硬體和 Docker 設定的測量請求數和延遲百分位數。將此處的任何靜態排名視為與線束的測試系列和儀表板的內建判決副本一致的定性模式。
2. 什麼是多語言基準?
多語言基準 託管於 多語言基準.fictionally.org (工作流示例生態系統中虛構品牌的基礎設施)。登陸標題比較:
- NGINX NJS — Stock NGINX 中的 JavaScript 模組
- OpenResty Lua — Lua 處於 OpenResty 的邊緣
- Python FastAPI — Uvicorn ASGI 應用程式
- 轉到網路/http — 標準庫伺服器
- Rust Actix-web — Actix 上的異步 HTTP
- 包子 — 使用本機 HTTP 伺服器的 JavaScript 執行時
- Java (Javalin / Jetty) — Jetty 上的輕量級 JVM HTTP
- Kotlin (Ktor / Netty) — Netty 上協程友好的 JVM HTTP
直播標題是 8種語言 比較: njs、Lua、Python、Go、Rust、Bun、Java、Kotlin。副標題闡述了意圖:效能 長輪詢/聊天/佇列/API 工作負載 — 大量連線、大量 JSON 和大量路由的路徑,而不是單一的“hello world”戰車競賽。 JVM 商店最終獲得了與 Go/Rust/Bun 相同的公平表面,而不是一個單獨的“企業”軼事。
2.1 儀表板顯示內容
當執行進行時,UI 會進行輪詢 /data/results.json 每兩秒渲染一次:
- 請求/秒(吞吐量) — 彙總自
wrk每個語言每個測試 - 平均延遲 和 P99 尾部潛伏期 — 來自 wrk 延遲模型的毫秒數
- TTFB(第一個位元組的時間) — 來自curl 計時 JSON 和 wrk
- 彙總表 — 每次測試的獲勝者在最佳細胞上具有 ★ 標記
- 詳細的測試卡 — 條形圖和指標表(P50、P90、P99.9、錯誤)
- 延遲百分位分佈 - 測試的平均值
- 結論——最適合您的用例 - 一旦狀態為敘述
complete
這種結構故意是 ARB 友好的:幻燈片圖表、電子表格表格、ADR 風險部分的敘述。
3. 工作流程示例工具
一切可複製的東西都生活在 benchmarks/ 在 工作流程示例 儲存庫。頂層佈局:
benchmarks/
bench.sh # orchestrates tests, writes results.json
wrk_json.lua # wrk done() → JSON summary (RPS, percentiles)
docker-compose.yml # eight app services + dashboard + bench runner
njs/ # NGINX + njs module
lua/ # OpenResty nginx.conf
python/ # FastAPI + Dockerfile
golang/ # net/http main.go
rust/ # Actix-web + Cargo
bun/ # Bun server.ts
java/ # Javalin on Jetty
kotlin/ # Ktor on Netty
dashboard/ # static index.html + nginx.conf
3.1 Docker Compose拓撲
docker-compose.yml 定義共享網路上的隔離服務:
nginx-njs— 埠 8081,配置來自./njsopenresty-lua— 埠 8082python-fastapi— 埠 8084,構建於./pythongo-server— 埠 8085rust-actix— 埠 8086bun-server— 埠 8087java-server— 埠 8088,Javalin / Jetty 來自./javakotlin-server— 埠 8089,Ktor / Netty 來自./kotlindashboard— 埠 8083,提供 HTML 服務並安裝results體積在/databench— 安裝的 Alpine 容器curl,wrk,jq,等待依賴關係,執行bench.sh
板凳跑者分享 results 與儀表板的音量,因此結果實時顯示,無需手動複製。
3.2 bench.sh方法論
shell 驅動程式顯式地編碼公平規則:
- 期間:
10s每個端點每種語言 - 主題: 4
- 連線: 100個併發
- 熱身: 50發射擊
/hello在定時測試之前在每臺伺服器上 - 每臺伺服器: 捲曲計時 JSON(dns、connect、ttfb、total)加上 wrk
wrk_json.lua
指令碼中的七個測試是用豎線分隔的:
| ID | 姓名 | 意圖 | 端點 |
|---|---|---|---|
| 1 | 純文字 | 基線——最小響應、框架開銷 | /hello |
| 2 | JSON序列化 | 構建並序列化 100 項 JSON 陣列 | /json |
| 3 | CPU-繫結(fib 30) | 遞迴斐波那契(30) — 純 CPU | /cpu?n=30 |
| 4 | 字串操作 | 構建、拆分、大寫、重新連線 1000 個段 | /string |
| 5 | 請求檢查 | 標頭、方法、引數 → JSON | /request_info?foo=bar&baz=123 |
| 6 | 子請求+轉換 | 內部子請求、解析JSON、轉換 | /subrequest |
| 7 | 路由邏輯 | 查詢引數的條件路由 | /route?action=greet&name=bench |
每種語言都實現相同的路線表面(請參閱 golang/main.go, python/main.py, java/, kotlin/、NGINX 配置等),因此差異反映了執行時和框架,而不是不匹配的規格。
4. 為什麼“多語言”很重要(沒有狂熱)
多語言架構並不意味著每個工程師都學習八種語言。這意味著 有界上下文 獲得適合的執行時:
- 邊平面 — 身份驗證、速率限制、路由:您已經在 NGINX 中執行 Lua 或 njs
- 核心API平面 — SLO 的業務邏輯:Go 或 Rust
- JVM平面 — 現有的 Spring/Jakarta 莊園、共享庫、招聘深度:Java (Javalin) 或 Kotlin (Ktor)
- 資料平面 — ETL、筆記本、ML 膠水:Python
- 實時JS飛機 — WebSockets,與前端共享的型別:速度獲勝的 Bun 或 Node
統一堆疊最佳化人力資源和採購。多語言基準最佳化 適合每個工作負載 並進行可衡量的權衡。
5. 重要的尺寸
原始請求/秒是 Slack 上傳輸速度最快的指標。也是最容易誤讀的。使用多列標題:
| 標準 | 當…時占主導地位 | 線束訊號 |
|---|---|---|
| p50 / p99 潛伏期 | 面向使用者的 API、聊天、長輪詢 | wrk 延遲百分位數;儀表板P99圖表 |
| 吞吐量(RPS) | 高扇出閘道器、批次聚合器 | 工作 RPS;獲獎者總結專欄 |
| 每個連線的記憶體 | 數千個閒置 WebSocket | 定性+生產分析(未完全掌握) |
| TTFB | CDN未命中、冷路徑、行動網路 | 捲曲 time_starttransfer 在結果 JSON 中 |
| LOC/複雜性 | 初創企業,受監管的變更控制 | 比較跨資料夾的實現 |
| 構建和 CI 時間 | 部署頻繁,服務眾多 | Docker 為每種語言構建配置檔案 |
| 運營負擔 | 小平臺團隊 | 現有 NGINX 技能 → Lua/njs;其他容器 |
| 託管費用 | 始終開啟與縮放至零 | 源自記憶體+負載下的CPU(生產) |
6. 決策矩陣
下圖是我們在評論中使用的定性地圖 - 說明性領導者,不能替代在您的套件上執行線束。

按行優先閱讀:選擇您的工作負載形狀,然後選擇權重列。如果兩個標準發生衝突(例如最佳 RPS 與最低 LOC),那麼 ADR 討論就值得討論這種張力。
7. 大小寫模式(示例標籤)
下面將測試系列與架構選擇進行了對映。跑步後,機器上的領先者會出現在儀表板上 - 不要將此部分視為固定分數。
7.1 API 延遲敏感(測試 1–2、5–7)
JSON API 和路由密集型處理程式映象測試 2、5 和 7。編譯的非同步執行時(Rust Actix、Go)通常在此類綜合 HTTP 基準測試中領先於吞吐量和尾部延遲; Bun 經常位於 JSON 密集的路徑上,具有 JS 人體工程學原理。 Java (Javalin) 和 Kotlin (Ktor) 讓 JVM 團隊能夠公平地瞭解那些走相同路線的領導者——當問題是“用更輕的堆疊留在 JVM 上”與“用 Go/Rust 重寫”時,這很有用。 Python FastAPI 用原始 RPS 來換取開發速度——儀表板判決明確指出了這一點。
7.2 CPU繫結的微工作(測試3)
Fibonacci(30) 隔離 CPU,無需 I/O。期待 Rust 和 Go 能夠大放異彩;解釋堆疊支付開銷;預熱後,JVM JIT 看起來比冷的 10 秒視窗所暗示的更強大 — 如果這是您的真實配置檔案,請延長持續時間。如果您的實際服務受 I/O 限制,請不要過度重視這一行 — 這是對計算密集型中介軟體的壓力測試,而不是典型的 CRUD。
7.3 邊緣變換(測試 6-7,NGINX 變體)
子請求和路由測試在哪裡 OpenResty Lua 和 NGINX NJS 屬於:零額外跳躍、共享工作記憶體、運維團隊已經管理 NGINX。該工具的結論建議將 Go/Rust 用於核心聊天/佇列後端,而將 Lua/njs 用於邊緣——這是許多企業已經非正式執行的明智劃分。
7.4 批次ETL和資料管道
HTTP 工具不會模擬 Spark 或倉庫負載。對於批處理,團隊通常會優先考慮 Python 生態系統和編排(Airflow、Dagster)或 Go 工作執行緒以提高吞吐量。使用多語言基準 API 表面和控制平面 這些作業公開,而不是針對批處理引擎本身。
7.5 快速內部工具
具有低 QPS 和高變更率的內部管理 API:Python 或 Bun/Node 通常在速度和招聘方面獲勝。執行測試 2 (JSON) 和測試 5(檢查)以確保開銷是可以接受的;如果 p99 的連線數峰值低於 100 個,請在升級到面向客戶的級別之前重新考慮。
7.6 JVM 空間(Java 和 Kotlin)
許多企業已經執行 Java 或 Kotlin 來實現共享庫、合規工具和招聘深度。安全帶的 java-server (Jetty 上的 Javalin,埠 8088)和 kotlin-server (Netty 上的 Ktor,埠 8089)實現與 Go 和 Rust 相同的七個端點,因此您可以在重寫之前量化較輕的 JVM HTTP 堆疊對於給定的 SLO 是否“足夠好”。當協程式併發和 Kotlin 優先團隊很重要時,首選 Kotlin;當週圍的環境和庫圖已經以 Java 為中心時,更喜歡 Java。使用實時儀表板行 - 不要假設 Spring Boot 編號等於 Javalin/Ktor 編號。
8. 工作流程圖

可重現的迴圈:指定工作負載→執行 Compose 工具→將結果釋出到 Fictionally 儀表板(或您的內部克隆)→使用配置後設資料記錄 ADR→在執行時或硬體更改時重新執行。
9. 如何進行自己的比較
- 克隆:
git clone https://github.com/bwalia/workflow-examples.git && cd workflow-examples/benchmarks - 啟動堆疊:
docker compose up --build— 構建所有語言映像,在埠 8083 上啟動儀表板,自動執行工作臺。 - 手錶: 開啟
http://localhost:8083(或託管執行處於活動狀態時的公共站點)。 - 延長: 新增資料夾
myruntime/,映象端點路徑,在中註冊服務docker-compose.yml,將伺服器附加到SERVERS在bench.sh. - 自定義負載: 編輯
DURATION,THREADS,CONNECTIONS在頂部bench.sh— 記錄 ADR 中的變更。 - 新增生產型測試: 例如auth 中介軟體、ORM 查詢、50KB 負載 — 保持跨語言的一致性。
對於 CI,在夜間工作流程中執行 Compose,存檔 results.json 作為工件,並且僅在您定義的迴歸閾值上失敗(例如,在測試 2 中,p99 每週增加 20%)。
10.反模式
- 僅選出測試 1 的獲勝者 — 純文字有利於最小的堆疊;它忽略了 JSON、CPU 和路由難題。
- 忽視團隊能力 — 在沒有導師的情況下,生產中的 Rust 在事故發生時成本高昂。
- 忽略託管成本 — 如果每個 Pod 的記憶體使您的賬單翻倍,那麼 2× RPS 就沒用了。
- 在整個組織範圍內強制使用一種語言 - 破壞合法的邊緣與核心分裂。
- 替換生產分析 — 合成 HTTP ≠ 您的 ORM、快取或區域延遲。
- 不同硬體的比較 — 膝上型電腦 Docker ≠ 裸機 ≠ K8s 限制;請注意 ADR 中的類別。
11. 工程領導力的好處
- ARB 包 — 匯出儀表板螢幕截圖 +
results.json+ 編寫雜湊。 - 供應商中立的證據 — 沒有來自單一雲或框架供應商的銷售平臺。
- 入職清晰度 — 新員工瞭解*為什麼*服務 A 是 Go,服務 B 是 Python。
- 降低風險 — 在重寫之前在影子服務中試執行亞軍。
- 金融運營對話 — 將尾部延遲連結到自動縮放和記憶體空間。
- 平臺路線圖 — 與其他 K8s 微服務相比,證明 NGINX 技能投資的合理性。
12. 限制
- 綜合工作負載 — 七個 HTTP 測試無法代表 Kafka 消費者、GPU 作業或複雜的 ORM 圖。
- Docker 網路 ——增加開銷;絕對數量與裸機不同。
- 單機類 — 託管結果反映了虛構使用的任何硬體;你的數字會有所不同。
- 無持久層 — 設計上不存在資料庫和快取效果。
- 執行時間短 — 每次測試 10 秒可能不會暴露 GC 暫停或預熱懸崖;延長壓力活動。
將連續分析(eBPF、APM、針對登臺的負載測試)作為生產的真實來源。多語言基準縮小了範圍 語言和框架 與可重複的基線進行辯論。
13. 結論
預設堆疊偏差很舒服;這也是團隊為作業提供錯誤執行時的方式。 多語言基準 和 工作流程示例 駕馭轉向“哪種語言獲勝?”進入“哪種語言獲勝 對於該工作負載行?” — 帶有您的 ARB 可以引用的圖表。
分叉儲存庫,新增看起來像熱路徑的端點,執行 Compose,並將結果附加到下一個架構決策。同伴 部落格文章 是五分鐘的分享版本;這篇文章是參考。
釋出者: Workstation (workstation.co.uk)。基準儀表板託管於 多語言基準.fictionally.org 在虛構示例生態系統中。
本文的 SEO 快照
- 搜尋引擎最佳化標題: 多語言基準:適合工作的正確工具
- 元描述: 在相同的 HTTP 工作負載上比較 njs、Lua、Python、Go、Rust、Bun、Java 和 Kotlin。可複製的工具、實時儀表板、建築師的決策矩陣。
- 主要關鍵詞: 多語言基準、語言比較、架構決策、工作流程示例、效能基準、Rust 與 Go、Java 與 Kotlin、FastAPI、Javalin、Ktor
- Twitter / X(280 個字元以下): 多語言基準:跨 njs、Lua、Python、Go、Rust、Bun、Java、Kotlin 的相同 7 個 HTTP 測試 — 實時儀表板 + 工作流程示例工具。沒有一個贏家;決策框架。 #Rust #GoLang #Java #Kotlin #Bunjs #polyglot
- 領英帖子: 我們發表了一篇關於多語言基準的深入研究——如何停止從習慣中選擇一個組織範圍的堆疊,並開始將執行時與工作負載相匹配。八種語言(包括 Java/Javalin 和 Kotlin/Ktor)、七種可比較的測試、Docker Compose + wrk、polyglot-benchmarks.fictionally.org 上的實時結果,來源為 github.com/bwalia/workflow-examples/tree/main/benchmarks。包括決策矩陣、反模式和 ADR 指南。來自 Workstation 工程。 #Rust #GoLang #Java #Kotlin #Bunjs #Lua #Python #njs #FastAPI #Javalin #Ktor #OpenResty #polyglot #benchmarks