負載測試會找出 Databricks Apps 代理在效能下降前能承受的最大每秒查詢次數(QPS)。 本頁會展示如何完成以下操作:
- 部署一個模擬版本的代理程式,以隔離基礎設施吞吐量與 LLM 延遲。
- 用 Locust做一個漸進到飽和的負載測試。
- 透過互動式儀表板分析結果。
你可以利用 Claude Code 技能跟隨 AI 輔助路徑,或手動設定每個步驟。
Requirements
- 一個Azure Databricks工作區,啟用了 Databricks 應用程式。
- 一個已部署(或準備部署)於 Databricks 應用程式上的代理應用程式,使用 OpenAI 代理 SDK、LangGraph 或自訂框架。 請參閱 使用舊版代理伺服器在 Databricks 應用程式上執行代理程式。
- Databricks CLI 已安裝並驗證。 請參閱安裝或更新 Databricks CLI。
- Python 3.10+ 搭配
uv套件管理器。 - (針對 AI 輔助路徑)已安裝 Claude 程式碼 。
- (大約 1 小時以上的負載測試)擁有 M2M OAuth 憑證(
client_id和client_secret)的服務主體。 請參見 使用 OAuth 授權服務主體存取至 Azure Databricks。- 對於短時間負載測試(少於 ~1 小時),你現有的使用者(U2M)OAuth 憑證
databricks auth login運作正常。 若測試較長,請使用 M2M OAuth 搭配服務主體——U2M 令牌在長程執行中會過期,導致測試中途失敗。 建立服務主體需要工作區管理員權限。
- 對於短時間負載測試(少於 ~1 小時),你現有的使用者(U2M)OAuth 憑證
建議採用 AI 輔助設定
如果你用 Claude Code,這項技能 /load-testing 會自動化工作流程。 它會讀取你的代理程式碼、產生模擬程式碼、建立負載測試腳本,並引導你完成部署流程。
Tip
請讓 Claude Code 來為你完成:
Clone https://github.com/databricks/app-templates and run the /load-testing skill against the {your-template} template.
或者按照以下步驟操作。
步驟 1:複製代理範本
這項技能 /load-testing 包含在 databricks/app-templates 的資料庫中,既是頂層 agent-load-testing 技能,也已預先同步到每個個別代理範本中。 如果你已經有來自app-templates的專案,那麼你已經有這項技能了。
複製倉庫並切換到要進行負載測試的代理程式模板目錄:
git clone https://github.com/databricks/app-templates.git
cd app-templates/{your-template}
步驟二:執行負載測試技能
在 Claude Code 中,執行:
/load-testing
這個技能會互動式地引導你完成以下步驟。 你可以跳過模擬測試來直接測試代理,或者如果應用程式已在執行,則可以跳過部署。
- 收集參數:詢問你的部署狀態、運算大小、工作者配置及 OAuth 憑證。
- 建立載入測試腳本:產生 、
locustfile.py和run_load_test.py,針對你的專案量身打造。 - 模擬你的 LLM:建立一個針對你的 SDK(OpenAI Agents SDK、LangGraph 或自訂)的模擬客戶端,用可設定的串流延遲取代真實的 LLM 呼叫。
- 部署測試應用程式:引導你部署多個不同計算大小與工作者數量的應用程式配置。
- 執行測試:使用 M2M OAuth 認證及 ramp-to-saturation 執行負載測試。
- 產生結果:產生一個互動式 HTML 儀表板,包含 QPS、延遲與失敗指標。
手動設定
請依照以下步驟設定並執行負載測試,無需 AI 協助即可。
步驟 1:模擬你代理人的 LLM 呼叫(可選)
如果你想要包含真實 LLM 延遲的端到端結果,可以跳過這一步。 要單獨衡量 Databricks Apps 的基礎設施吞吐量,可以模擬 LLM,避免其每次請求延遲(通常 1-30 秒)成為瓶頸。
模擬會回傳帶有可設定串流延遲的預設回應,保留完整的請求/回應流程(SSE 串流、工具派遣、SDK 執行器),只替換 LLM。 這能顯示 Databricks Apps 平台能提供的最高 QPS,並避免在負載測試時產生 Foundation Model API 令牌成本。
模擬時間由兩個環境變數控制:
| 變數 | Default | 描述 |
|---|---|---|
MOCK_CHUNK_DELAY_MS |
10 |
串流文字區塊之間的毫秒延遲 |
MOCK_CHUNK_COUNT |
80 |
每個回應的文字區塊數量 |
預設情況下,每個模擬回應約需 800 毫秒(10 毫秒 x 80 區塊),明顯快於真實的 LLM 回應(3-15 秒)。 吞吐量數字反映的是平台,而非模型。
建立一個模擬客戶端,取代真正的大型語言模型客戶端。 其餘的代理程式碼保持不變,而方法則取決於你的 SDK。 關於 OpenAI,請參見 mock_openai_client.py 的參考實作databricks/app-templates。 同樣的模式也會適用於其他 SDK。
OpenAI 智能代理 SDK
Create agent_server/mock_openai_client.py — 實作MockAsyncOpenAI並包含串流的chat.completions.create()類別。 它會即時回傳工具呼叫區塊(模擬大型語言模型決定呼叫工具的過程),而文字回應區塊的延遲則可透過 MOCK_CHUNK_DELAY_MS 和 MOCK_CHUNK_COUNT 環境變數進行設定。
將它替換到你的代理中:
from agent_server.mock_openai_client import MockAsyncOpenAI
from agents import set_default_openai_client, set_default_openai_api
set_default_openai_client(MockAsyncOpenAI())
set_default_openai_api("chat_completions")
其餘的代理程式碼(處理器、工具、串流邏輯)保持不變。
LangGraph
將 ChatDatabricks 模型替換為一個回傳預先建構 AIMessage 物件的模擬:
# Before:
# model = ChatDatabricks(endpoint="databricks-claude-sonnet-4-6")
# After:
from agent_server.mock_llm import MockChatModel
model = MockChatModel()
模擬應在第一次呼叫時回傳帶有工具呼叫的物件,後續呼叫時回傳 AIMessage 文字內容,並可設定串流延遲。
海關代理
將代理程式所進行的任何外部 API 呼叫(LLM、AI 搜尋、工具 API)都以模擬實作包裝,使其回傳逼真的回應格式,並支援可設定的延遲。
步驟 2:設定負載測試腳本
在你的專案中建立一個 load-test-scripts/ 目錄。 負載測試框架由三個與框架無關的腳本組成,且可與任何 Databricks Apps 代理程式搭配使用。
<project-root>/
agent_server/ # Your existing agent code
load-test-scripts/ # Load testing scripts (create this)
run_load_test.py # CLI orchestrator
locustfile.py # Locust test with SSE streaming + TTFT tracking
dashboard_template.py # Interactive HTML dashboard generator
load-test-runs/ # Results (auto-created per run)
<run-name>/
dashboard.html # Interactive dashboard
test_config.json # Test parameters for reproducibility
<label>/ # Per-config Locust CSV output
框架包含以下檔案:
-
locustfile.py:Locust 負載測試發送POST /invocations請求,並使用stream: true解析 SSE 串流,將第一個令牌的時間(TTFT)記錄為自訂指標,使用支持自動刷新功能的 M2M OAuth 令牌交換,實施StepRampShape算法,在每個等級維持step_size秒,同時將使用者數量從max_users增至step_duration。 -
run_load_test.py:一個 CLI 編排器,依序測試每個應用程式 URL,並在每個配置下提供獨立的指標。 它處理 OAuth 代幣刷新,每次測試前會執行健康檢查和預熱,並將結果儲存到load-test-runs/<run-name>/<label>/。 -
dashboard_template.py:利用 Chart.js 產生獨立的 HTML 儀表板,包含 KPI 卡、條狀圖(QPS、延遲、配置下的 TTFT)、QPS 坡度進度線圖及完整結果表。 可獨立執行:uv run dashboard_template.py ../load-test-runs/<run-name>/。
安裝依賴項
負載測試腳本會在 pyproject.toml 中使用它們自己的 load-test-scripts/,以避免污染代理的生產依賴。 創建 load-test-scripts/pyproject.toml:
[project]
name = "load-test-scripts"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
"locust>=2.32,<2.40",
"urllib3<2.3",
"requests",
]
Note
插腳 locust 到 <2.40。 較新版本>=2.43已知的RecursionError會破壞長負載測試。
請從 load-test-scripts/ 目錄中安裝:
cd load-test-scripts/
uv sync
步驟 3:部署具有不同配置的測試應用程式
部署多個 Databricks 應用程式,分別擁有不同的運算大小和工作者數量,以找到最適合你工作負載的最佳配置。
推薦測試矩陣
以下配置聚焦於先前測試中識別出的最佳點。 如果你想要更廣泛的覆蓋範圍,可以在兩側各加一個設定(例如, medium-w1 或 large-w12),但通常下面六個配置就足夠了。
| 計算大小 | 工人 | 建議應用程式名稱 |
|---|---|---|
| Medium | 2 | <your-app>-medium-w2 |
| Medium | 3 | <your-app>-medium-w3 |
| Medium | 4 | <your-app>-medium-w4 |
| 大型 | 6 | <your-app>-large-w6 |
| 大型 | 8 | <your-app>-large-w8 |
| 大型 | 10 | <your-app>-large-w10 |
設定計算大小
在建立或更新應用程式時,使用 Databricks CLI 設定運算大小:
# Create a new app with Medium compute
databricks apps create <app-name> --compute-size MEDIUM
# Update an existing app to Large compute
databricks apps update <app-name> --compute-size LARGE
用宣告式自動化套件來設定工作者數量
start-server (透過 AgentServer.run())直接接受 --workers 標誌。 使用 DAB 變數將工作者計數傳入 command 陣列:
variables:
app_name:
default: 'my-agent-medium-w2'
workers:
default: '2'
resources:
apps:
load_test_app:
name: ${var.app_name}
source_code_path: .
config:
command: ['uv', 'run', 'start-server', '--workers', '${var.workers}']
env:
- name: MOCK_CHUNK_DELAY_MS
value: '10'
- name: MOCK_CHUNK_COUNT
value: '80'
targets:
medium-w2:
default: true
variables:
app_name: 'my-agent-medium-w2'
workers: '2'
large-w8:
variables:
app_name: 'my-agent-large-w8'
workers: '8'
部署與驗證
部署每個目標時,請使用 Databricks CLI:
databricks bundle deploy --target medium-w2
databricks bundle run load_test_app --target medium-w2
在執行負載測試前,先確認應用程式是否已啟用:
databricks apps get <app-name> --output json | jq '{app_status, compute_status, url}'
Note
等所有應用程式都達到 ACTIVE 狀態後再繼續。 還在啟動的應用程式會產生誤導性的結果。
步驟四:執行負載測試
設定認證
根據你的執行時間長短選擇驗證方式:
-
簡短測試(少於 ~1 小時):使用你現有的使用者憑證。
databricks auth login不需要額外設定。 - 長時間測試(超過~1小時,例如夜間運行):使用M2M OAuth搭配服務主體。 U2M 代幣會在測試中途過期並中斷您的測試執行。 建立服務主體需要工作區管理員權限。
對於 M2M OAuth,執行測試前先匯出服務主體憑證:
export DATABRICKS_HOST=https://your-workspace.cloud.databricks.com
export DATABRICKS_CLIENT_ID=<your-client-id>
export DATABRICKS_CLIENT_SECRET=<your-client-secret>
參數參考
| 參數 | Required | Default | 描述 |
|---|---|---|---|
--app-url |
Yes | — | 應用程式網址測試(可重複使用) |
--client-id |
長時間的測試 |
DATABRICKS_CLIENT_ID 環境 |
服務主體識別碼(M2M OAuth) |
--client-secret |
長時間的測試 |
DATABRICKS_CLIENT_SECRET 環境 |
服務主體客戶端密鑰 (M2M OAuth) |
--label |
No | 由網址自動導出 | 每個應用程式的人類可讀標籤(可重複) |
--compute-size |
No | 自動偵測或 medium |
每個應用程式的計算尺寸標籤: medium, large(可重複) |
--max-users |
No | 300 |
最大同時虛擬用戶 |
--step-size |
No | 20 |
每個增長步驟新增的使用者 |
--step-duration |
No | 30 |
每階梯的秒數 |
--spawn-rate |
No | 20 |
使用者生成率(使用者/秒數) |
--run-name |
No | <timestamp> |
本次運行名稱 — 結果已儲存至 load-test-runs/<run-name>/ |
--dashboard |
No | 關閉 | 測試完成後產生互動式 HTML 儀表板 |
範例指令
快速單一應用程式測試(短程——使用你的 databricks auth login 會話):
cd load-test-scripts/
uv run run_load_test.py \
--app-url https://my-app.aws.databricksapps.com \
--dashboard --run-name quick-test
完整矩陣涵蓋推薦的6種配置(長期使用——通過M2M認證)。 與--compute-size相同的順序傳遞--app-url旗標:
uv run run_load_test.py \
--app-url https://my-app-medium-w2.aws.databricksapps.com \
--app-url https://my-app-medium-w3.aws.databricksapps.com \
--app-url https://my-app-medium-w4.aws.databricksapps.com \
--app-url https://my-app-large-w6.aws.databricksapps.com \
--app-url https://my-app-large-w8.aws.databricksapps.com \
--app-url https://my-app-large-w10.aws.databricksapps.com \
--compute-size medium --compute-size medium --compute-size medium \
--compute-size large --compute-size large --compute-size large \
--client-id $DATABRICKS_CLIENT_ID \
--client-secret $DATABRICKS_CLIENT_SECRET \
--dashboard --run-name overnight-sweep
多次跑動以求統計一致性:
for RUN in r1 r2 r3 r4 r5; do
uv run run_load_test.py \
--app-url https://my-app.aws.databricksapps.com \
--client-id $DATABRICKS_CLIENT_ID \
--client-secret $DATABRICKS_CLIENT_SECRET \
--max-users 1000 --step-size 20 --step-duration 10 \
--run-name my_test_${RUN} --dashboard || break
done
執行過程中會發生什麼事
-
健康檢查:驗證應用程式的串流是否正確(能夠接收
[DONE])。 - 預熱:依序發送請求來預熱應用程式。
- 「達到飽和」:每秒增加同時在線用戶。
- 飽和偵測:當 QPS 在增加更多用戶後仍達到瓶頸時,就已經達到吞吐量上限。
預估的持續時間
每個被測的應用程式都會經過自己的斜坡,因此總執行時間會隨著矩陣中的配置數量而調整。 請使用以下公式規劃你的跑步時間。
每個應用程式的持續時間: (max_users / step_size) * step_duration 秒。
預設值為 :--max-users 300 --step-size 20 --step-duration 30
- 15 步 x 30 秒 = 每個應用程式約 7.5 分鐘
- 建議的6組組態矩陣:每次執行約45分鐘
步驟 5:檢視和解譯結果
打開儀表板:
open load-test-runs/<run-name>/dashboard.html(可選)例如,從現有資料重新建立儀表板,例如在更新範本後:
cd load-test-scripts/ uv run dashboard_template.py ../load-test-runs/<run-name>/
儀表板區段
互動式儀表板包含:
- KPI 卡:最佳配置(依峰值成功 QPS)、整體峰值 QPS、最低延遲及服務的總請求數。
- 按配置分類的 QPS:分組條狀圖,顯示中位數 QPS、不含故障的峰值 QPS,以及各配置下的峰值 QPS 並列比較。
- 依設定延遲:分組顯示 p50 和 p95 延遲的條狀圖。
- TTFT 根據配置:第一字節時間(p50 和 p95)。
- 完成的總請求數:每個配置的請求次數。
- QPS Ramp Progression:折線圖,並標示 QPS、QPS(不包括失敗)、延遲與故障。 包含用於調整最大使用者數量的滑桿,可放大至較低的並發數範圍。 圖表依計算大小分組(中型與大型並列)。
- 完整結果表:所有有峰值 QPS、峰值使用者、延遲百分位數及故障率的配置。
- 測試參數:配置摘要以提升重現性。
如何解讀結果
- 峰值QPS:在任何斜坡階級達到的最大QPS。 這就是該配置的吞吐量上限。
- 高峰用戶數:達到高峰 QPS 時的同時在線用戶數。 在此點之後增加更多使用者並不會提升吞吐量。
- 失敗率:應為0% 或非常低。 高失敗率代表應用程式在該並發層級已經過載。
- QPS 坡度圖:尋找線條變平的地方。 這就是飽和點:增加更多用戶不會提升吞吐量。
基於合成資料的基準測試執行
本節報告內部 Azure Databricks 基準測試與合成代理應用程式的測量結果,該測試中每個 LLM 呼叫都被模擬。 這是與對你自己的代理程式進行負載測試分開的另一項練習:用它來了解你可以預期的結果大致樣貌,並作為容量規劃的粗略起點。
這次跑映展現了什麼
- 建議起始點:2 名 Medium 運算,或 8 名 Large 運算。
- 更多員工不一定更好。 在中等難度下,2 名工人(155.1 QPS)以 ~33%擊敗 4 名工人(116.5 QPS)。 模擬工作負載受 CPU 限制,因此一旦超過 2 個工作程序,就會出現 CPU/記憶體爭用,進而抵銷額外的平行化效益。 一個真正受 IO 綁定且主要待在模型端點的代理,可能比這個模擬更可擴展,所以務必測試你自己的代理。
- 運算規模:大型運算量約為中型運算的 2.2 倍(278.0 對平均 123.5 個峰值 QPS)。
- 延遲:Large 約比 Medium 低 20%(p50 約為 906 毫秒,相較於 Medium 的 1,180 毫秒),而 TTFT 在 Large 上約為 1,100 毫秒,Medium 則為 1,720–1,820 毫秒。
- 可靠性:即使有 1,000 名同時使用者,故障率仍維持在 0 或接近 0%。
由於 LLM 為模擬方式處理(串流以固定的每區塊延遲進行模擬),因此這些數據反映的是基礎設施吞吐量,而非端對端代理系統的指標。 它們衡量的是 Databricks 應用程式 FastAPI AgentServer 能平行處理多少請求,而非真實模型的延遲。 呼叫即時大型語言模型端點的生產環境代理程式,QPS 較低且延遲較高,主要由模型回應時間主導。 你自己的數字會隨著代理的複雜度、有效載荷大小、工具呼叫、區域以及你所呼叫的模型端點而有所不同。 為了準確評估容量,請針對您自己的代理程式執行負載測試。
以下表格結果顯示了各組態的完整細分。
測試條件
- 基準執行:針對 8 種應用程式組態(4 個中型運算、4 個大型運算)各進行 5 個相同的輪次,且每種組態的 uvicorn 工作程序數皆不同。
- Ramp:同時支援 20 至 1,000 名同時使用者,分 20 名用戶每段等待 10 秒(每次配置 50 步)。
- 模擬代理:每次請求會串流傳回約 95 個區塊,模擬 LLM token 串流。
- 總請求量:所有跑線合計約 146 萬件。
按配置分類的峰值 QPS
峰值 QPS 為 5 次執行結果的平均值。
| 計算大小 | 工人 | 平均峰值 QPS | 峰值分布範圍 | 失敗率 |
|---|---|---|---|---|
| Medium | 2 | 155.1 | 137.0-166.6 | 0.0% |
| Medium | 4 | 116.5 | 112.6-121.8 | 0.1% |
| Medium | 6 | 111.9 | 102.6-117.5 | 0.0% |
| Medium | 8 | 110.3 | 108.3-112.1 | 0.0% |
| 大型 | 6 | 281.6 | 268.2-292.4 | 0.0% |
| 大型 | 8 | 268.2 | 265.8-271.0 | 0.0% |
| 大型 | 10 | 288.1 | 280.3-299.4 | 0.0% |
| 大型 | 12 | 274.2 | 269.4-278.8 | 0.0% |
按運算規模平均:
| 計算大小 | 平均峰值 QPS | 平均QPS |
|---|---|---|
| Medium | 123.5 | 45.5 |
| 大型 | 278.0 | 100.1 |
在這次運算中,大型運算的吞吐量約為中型運算的 2.2 倍。
Troubleshooting
| Issue | Solution |
|---|---|
| 認證令牌在測試中途過期 | 對於超過 ~ 1 小時的測試,請從 U2M 切換到 M2M OAuth,並傳遞 --client-id 和 --client-secret |
| 健康檢查失敗 | 確認應用程式是否啟用: databricks apps get <name> --output json |
| 0 QPS 或無結果 | 檢查 load-test-runs/<run-name>/<label>/locust_output.log 中的錯誤 |
| 儘管用戶數量眾多,QPS 卻偏低 | 這個應用程式已經飽和了。 試試更多工人或更大運算能力。 |
| 高故障率 | 應用程式已經過載了。 減少 --max-users 或增加工作者/運算能力。 |
| 儀表板顯示沒有斜坡資料 | Verify results_stats_history.csv 存在於每個結果子目錄中 |
其他資源
- 用真實的 LLM 呼叫來測試:跳過模擬步驟,直接部署你的實體代理,來測量端到端延遲,包括 LLM 回應時間。
- 調整工作者數量:利用測試矩陣結果來找出您計算資源的最佳工作者數。
- 教學:評估並改進代理 ,以衡量準確性、相關性與安全性,同時衡量吞吐量。
- 如需了解完整的正式上線準備流程(包括 AI Gateway),請參閱讓你的 Databricks Apps 代理程式做好正式上線準備。