多租户與多站點架構:如何選擇
我看過團隊花上幾個月爭論多租戶與多站點架構,最後選錯了,又花另外六個月進行遷移。這是那種在你深入三個衝刺之後才會意識到問題的決策——你的內容編輯可能會不小心發佈到錯誤的品牌,或者你的部署管道需要花 45 分鐘,因為你在重建十二個站點,而實際上只有一個改變了。
這不是理論上的比較。我已經構建了兩種模式——有時候對同一個客戶,因為第一次選擇沒有奏效。讓我帶你了解在做出這個決定時真正重要的是什麼。
目錄

清楚定義術語
這些術語經常被隨意使用,所以我們來確定一下。
多租戶架構
一個應用實例為多個租戶(品牌、客戶、地區)提供服務。他們共享相同的程式碼庫、相同的資料庫(通常是)和相同的部署。租戶隔離在應用層進行——通過中介軟體、資料庫模式或行級過濾。
把它想象成一棟公寓樓。每個人都共享結構、管道和電路。但每個單位都有自己的鎖。
多站點架構
每個站點是一個獨立的應用實例,具有自己的程式碼庫(或共享程式碼庫的分支)、自己的資料庫和自己的部署管道。他們可能共享設計系統或元件庫,但他們是獨立部署和運營的。
這更像一個住宅開發區。同一個建築商、類似的藍圖,但每棟房子都有自己的基礎。
混合區域
說實話,大多數生產系統都落在兩者之間。你可能有一個多租戶 CMS 為獨立部署的前端提供內容。或者一個共享程式碼庫,被部署為每個租戶的獨立實例。真正的問題不是「選哪一個」,而是「在頻譜上的哪個位置」。
多租戶架構何時勝出
當你的站點相似之處大於差異時,多租戶架構就大放光彩。
強大的品牌一致性要求
如果你管理同一品牌的 15 個地區站點,並且設計需要保持鎖定,多租戶是你的朋友。一個程式碼庫意味著元件、佈局和交互模式的一個信息來源。當品牌團隊更新按鈕樣式時,它會在所有地方推出。
快速擴展到新租戶
我與一個特許經營平台合作,需要每週推出新的位置。使用多租戶,添加新站點只需要一個資料庫條目和一個 DNS 記錄。沒有新的基礎設施,沒有新的部署。上線時間從兩週縮短到大約 30 分鐘。
集中內容運營
當你有一個小型內容團隊管理多個資產時,多租戶將所有內容保持在一個地方。編輯者登入一個系統,切換上下文,並管理所有租戶的內容。無需為十多個 CMS 實例處理認證。
共享功能開發
每個你構建的功能都同時造福所有租戶。錯誤修復、性能改進、新整合——部署一次,到處受益。開發工作的投資回報率是倍增的。
多站點架構何時勝出
當你的站點需要顯著差異時,多站點架構就勝出。
完全不同的用戶體驗
如果品牌 A 是電子商務店面,品牌 B 是內容出版物,將他們塞進一個程式碼庫會造成混亂。我見過多租戶程式碼庫,其中 60% 的程式碼在租戶特定的條件後面。在那一點上,你沒有一個應用——你有幾個糟糕的應用共享一個倉庫。
不同的技術要求
也許一個站點需要 Next.js 來實現其動態、應用程式式的體驗,而另一個是一個完美適合 Astro 的內容豐富的站點。多站點讓每個資產使用正確的工具。我們構建了投資組合,其中一些站點運行在 Next.js 上,其他運行在 Astro 上,所有這些都從 共享無頭 CMS 獲取。
獨立發布週期
當不同的業務單位擁有不同的站點並且需要按自己的時間表發布時,多租戶會造成瓶頸。租戶 A 的新功能的部署不應該需要對租戶 B 到 Z 進行回歸測試。多站點為每個團隊提供自主權。
監管或資料隔離
某些行業需要硬資料隔離——不只是應用層分離,而是物理上獨立的資料庫,可能在不同的地區。醫療保健、金融和政府專案通常強制要求這一點。多站點使合規變得簡單直接,因為隔離是架構上的,而不僅僅是邏輯上的。
不同的性能特性
如果一個租戶獲得 1000 萬次月度訪問,而另一個獲得 5 萬次,共享基礎設施意味著你要麼為小租戶過度配置,要麼為大租戶配置不足。獨立部署讓你為每個資產合理規模。

決策框架
這是我與客戶一起使用的框架。為你的情況給每個因素打分:
| 因素 | 支持多租戶 | 支持多站點 |
|---|---|---|
| 站點相似度 | 80% 以上的共享 UI/功能 | 少於 50% 的共享 |
| 資產數量 | 10 個以上站點 | 少於 5 個站點 |
| 增長率 | 經常添加站點 | 穩定,很少添加 |
| 團隊結構 | 一個中央團隊 | 每個站點有獨立團隊 |
| 內容模型 | 相同或幾乎相同 | 顯著不同 |
| 合規需求 | 標準要求 | 嚴格的資料隔離 |
| 技術棧 | 所有地方相同的框架 | 需要不同的框架 |
| 發布節奏 | 協調發布可以 | 需要獨立發布 |
| 自定義深度 | 主題級(顏色、標誌) | 結構級(佈局、功能) |
| 預算 | 為效率優化 | 為靈活性優化 |
如果你大多在一列得分,決定很清楚。如果你在中間分裂,你可能在尋找混合方法——這很好。
實踐中的架構模式
讓我用程式碼具體化。
Next.js 的多租戶
我使用最常見的模式是基於中介軟體的租戶解析:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
const TENANT_MAP: Record<string, string> = {
'brand-a.com': 'brand-a',
'brand-b.com': 'brand-b',
'brand-c.com': 'brand-c',
};
export function middleware(request: NextRequest) {
const hostname = request.headers.get('host') || '';
const tenantId = TENANT_MAP[hostname] || 'default';
// 通過標頭傳遞租戶上下文
const response = NextResponse.next();
response.headers.set('x-tenant-id', tenantId);
// 如果需要,重寫到租戶特定的路徑
const url = request.nextUrl.clone();
url.pathname = `/${tenantId}${url.pathname}`;
return NextResponse.rewrite(url);
}
然後你的頁面元件拉取租戶特定的配置:
// lib/tenant-config.ts
export async function getTenantConfig(tenantId: string) {
// 可能來自資料庫、CMS 或配置檔案
return {
theme: await fetchTheme(tenantId),
navigation: await fetchNavigation(tenantId),
features: await fetchFeatureFlags(tenantId),
locale: await fetchLocaleConfig(tenantId),
};
}
這在租戶開始需要不同的頁面結構、不同的資料獲取策略或不同的第三方整合之前效果很好。那時條件邏輯就開始偷偷進來了。
帶有共享套件的多站點
對於多站點,我使用帶有共享套件的 monorepo:
├── apps/
│ ├── brand-a/ # Next.js 應用
│ ├── brand-b/ # Astro 應用
│ └── brand-c/ # Next.js 應用
├── packages/
│ ├── ui/ # 共享元件庫
│ ├── cms-client/ # 共享 CMS 整合
│ ├── analytics/ # 共享分析包裝器
│ └── config/ # 共享 TypeScript/ESLint 配置
├── turbo.json
└── package.json
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"deploy": {
"dependsOn": ["build"]
}
}
}
Turborepo(或 Nx)處理依賴圖,因此你只重建改變的內容。品牌 A 獲得新功能?只有品牌 A 重建和部署。共享 UI 套件更新?所有依賴於它的東西都重建。
混合:多租戶 CMS,多站點前端
老實說,這是我對大多數場景的最愛模式。你獲得集中內容管理和獨立前端部署:
┌─────────────────────┐
│ 無頭 CMS │
│ (Sanity/Contentful)│
│ 多租戶 │
│ 內容空間 │
└──────┬──────┬───────┘
│ │
┌───┘ └───┐
▼ ▼
┌──────┐ ┌──────┐
│站點 A│ │站點 B│
│Next.js│ │Astro │
└──────┘ └──────┘
內容編輯者獲得一個登入,可以管理所有資產。開發者獲得獨立程式碼庫和部署管道。對於有預算的團隊,這是兩全其美。
CMS 考量
你的 CMS 選擇顯著限制——或啟用——你的架構決定。
多租戶 CMS 支持
| CMS | 多租戶模型 | 多站點支持 | 定價影響 |
|---|---|---|---|
| Sanity | 每個租戶的資料集 | 優秀(單個專案中的多個資料集) | 免費層:2 個資料集;付費起 $99/月 |
| Contentful | 每個租戶的空間 | 良好(組織級管理) | 每個空間計入計劃;$300+/月 |
| Strapi | 單個資料庫,按租戶過濾 | 需要手動實現 | 自託管,隨基礎設施擴展 |
| Hygraph | 環境和階段 | 本地多站點內容聯合 | 從 $199/月起,適用於團隊計劃 |
| WordPress(無頭) | WordPress 多站點 | 成熟但複雜 | 每個站點的託管成本擴展 |
| Payload CMS | 集合級多租戶 | 日益增長的支持(v3.0+) | 自託管,開源 |
Sanity 的資料集模型對於多租戶設置特別優雅。每個租戶獲得自己的資料集,具有自己的模式,但它們位於一個專案下。你可以在資料集之間共享模式定義,同時允許租戶特定的自定義。規模大時(10 個以上租戶),這保持你的內容運營理智。
Contentful 的獨立空間方法有效,但成本增長很快。團隊計劃上的每個空間都花費真金白銀,你考慮添加空間之前已經在 $300/月。
內容建模含義
使用多租戶,你的內容模型需要適應所有租戶。這通常意味著:
- 每個內容類型上的
tenant或brand欄位 - 租戶特定的驗證規則
- 仔細的權限建模,使編輯者只看到他們租戶的內容
- 需要租戶範圍的共享內容類型(如「全局設置」)
使用多站點,每個站點有自己的內容模型。每個站點更簡單,但你喪失在站點之間共享內容的能力,除非沒有額外的內容聯合層。
性能和擴展
多租戶性能特性
多租戶的最大風險是「吵鬧的鄰居」問題。如果租戶 A 執行病毒式活動,流量增加 10 倍,所有租戶都會感受到它。緩解策略:
- 每個租戶的邊緣快取:使用 Vercel 或 Cloudflare 的邊緣網絡,快取鍵包括租戶識別符
- ISR 與租戶感知的重新驗證:只重新驗證內容改變的租戶的頁面
- 每個租戶的速率限制:保護共享資源免受任何單個租戶的壓倒
// next.config.js - ISR 與租戶感知的重新驗證
export async function generateStaticParams() {
const tenants = await getAllTenants();
const paths = [];
for (const tenant of tenants) {
const pages = await getTenantPages(tenant.id);
paths.push(...pages.map(page => ({
tenant: tenant.slug,
slug: page.slug,
})));
}
return paths;
}
多站點性能特性
每個站點獨立擴展。好消息就是這個。壞消息是你管理 N 個部署管道、N 個監控儀表板和 N 個性能預算集。超過 20 個站點,運營開銷成為瓶頸,而不是應用性能。
從我在 2025 年進行的基準測試,以下是你在 Vercel 上可能期望的大致情況:
| 指標 | 多租戶(1 個應用,10 個租戶) | 多站點(10 個應用) |
|---|---|---|
| 冷啟動(邊緣) | 20-50ms | 每個站點 20-50ms |
| 構建時間 | 8-15 分鐘(所有租戶) | 每個站點 2-4 分鐘 |
| 增量構建 | 30-90 秒 | 每個站點 30-90 秒 |
| 每個實例的內存 | 256-512MB 共享 | 每個 256-512MB |
| 月度 Vercel 成本(Pro) | ~$20 | ~$200($20 × 10) |
成本差異很大。多租戶在單個 Vercel Pro 計劃上以 $20/月,對比多站點需要企業版或創意專案組織。
成本分析
讓我們談談 12 個月內 10 個站點的投資組合的實際數字。
多租戶成本估計
| 項目 | 月度成本 | 年度成本 |
|---|---|---|
| Vercel Pro(1 個專案) | $20 | $240 |
| Sanity 團隊(1 個專案,10 個資料集) | $99 | $1,188 |
| 開發(初始構建) | -- | $40,000-60,000 |
| 維護(持續進行) | $2,000 | $24,000 |
| 第 1 年總計 | -- | $65,428-$85,428 |
多站點成本估計
| 項目 | 月度成本 | 年度成本 |
|---|---|---|
| Vercel Pro(10 個專案) | $200 | $2,400 |
| Sanity 團隊(10 個專案) | $990 | $11,880 |
| 開發(初始構建,共享套件) | -- | $50,000-80,000 |
| 維護(持續進行,10 個站點) | $4,000 | $48,000 |
| 第 1 年總計 | -- | $112,280-$142,280 |
多租戶大約便宜 40-60%,主要是因為維護負擔減少。但如果多租戶複雜性導致更多錯誤、較慢的功能開發或稍後的痛苦遷移,這些數字會翻轉。
想要針對你的具體情況的更精確估計?我們在我們的 發現流程 中詳細分解架構成本。
遷移策略
有時你從一種方法開始,需要切換。以下是如何在不燒毀一切的情況下進行的。
多租戶 → 多站點
這是更常見的遷移方向。跡象表明你需要它:
- 租戶特定代碼超過程式碼庫的 30%
- 部署被跨租戶回歸測試阻止
- 團隊正在踩到彼此的變更
策略:
- 首先將共享程式碼提取為套件(UI 元件、實用工具、CMS 客戶端)
- 圍繞現有應用建立 monorepo 結構
- 為最不同的租戶分支應用
- 逐漸將其他租戶移至自己的應用
- 隨著每個應用變成獨立應用,從中刪除租戶切換邏輯
多站點 → 多租戶
不太常見但會發生,通常在公司收購多個品牌並想要整合運營時。
- 審計所有站點以尋找共享模式(你會找到比預期更多的)
- 從最佳實現中構建共享元件庫
- 用最簡單的站點創建多租戶應用
- 一次一個站點遷移,在每個步驟驗證奇偶校驗
- 隨著租戶上線,停用單個應用
兩次遷移都是破壞性的。預算 3-6 個月和大量測試工作。這正是為什麼正確地進行初始決定很重要——它不只是一個架構選擇,它是一個承諾。
如果你面對這個決定,想與曾經做過的人談話,聯繫我們。
常見問題
多租戶和多站點架構之間有什麼區別? 多租戶使用單個應用實例為多個品牌或客戶提供服務,租戶隔離在應用層處理。多站點為每個站點部署獨立的應用實例,可能通過 monorepo 和元件庫共享程式碼。關鍵區別在於你運行一個應用還是許多應用。
我可以將多租戶 CMS 與多站點前端結合使用嗎? 絕對可以,通常是最好的方法。具有多個資料集的無頭 CMS(如 Sanity)為你提供集中內容管理,而獨立前端部署為每個站點在技術選擇、部署時間表和性能擴展方面提供獨立性。當你的站點共享內容結構但需要不同的用戶體驗時,這個混合模式特別有效。
多租戶架構如何影響 SEO? 多租戶應用根據域或子域提供不同內容,搜尋引擎處理得很好,只要你實現適當的規範 URL、每個租戶的唯一元資料和獨立站點地圖。風險在於租戶之間意外的內容重複——確保你的站點地圖生成和 robots.txt 是租戶感知的。從 SEO 角度來看,搜尋引擎不在乎你的站點是否共享程式碼庫;他們關心他們收到的內容和標記。
多租戶比多站點便宜嗎? 通常是的,通常在託管和維護成本上便宜 40-60%。你為一次部署、一個監控設置和一組基礎設施付費。然而,如果你的租戶明顯不同,多租戶在開發時間上可能變得更昂貴,因為管理租戶特定邏輯的複雜性非線性增長。損益平衡點取決於你的站點實際相似程度。
哪種方法對無頭 WordPress 多站點更好? WordPress 多站點本質上是多租戶——一個 WordPress 安裝,多個站點。如果你將 WordPress 用作無頭 CMS,多站點網絡為你提供集中內容管理。你的前端可以是多租戶(一個 Next.js 應用)或多站點(每個 WordPress 站點的獨立應用)。對於大多數基於 WordPress 的專案,我建議混合方法:WordPress 多站點作為 CMS,每個站點的獨立前端部署。
如何跨多租戶應用處理共享認證? 使用集中認證提供者(Auth0、Clerk 或 NextAuth.js)與租戶感知的會話管理。驗證令牌應包括租戶上下文,你的中介軟體應驗證經過認證的使用者有權訪問請求的租戶。資料庫中的行級安全(Supabase 和 Neon 都支持此)增加了防止跨租戶資料洩露的第二層保護。
多租戶應用最多可以處理多少個租戶? 沒有硬限制,但實際限制圍繞構建時間和運營複雜性出現。使用 Vercel 上的 Next.js ISR,我看過多租戶應用有效處理 50 個以上租戶。超過 100 個租戶,你會想查看按需 ISR,而不是預生成所有頁面,並且你需要複雜的快取策略。SaaS 平台(如 Shopify)有效地運行數千個租戶,但他們在那個基礎設施上投入了多年。
我應該為多站點架構使用 monorepo 嗎? 幾乎總是應該。具有 Turborepo 或 Nx 的 monorepo 為你提供多租戶的程式碼共享好處(共享元件、實用工具、配置),以及多站點的部署獨立性。關鍵是保持共享套件定義清晰和版本控制。沒有 monorepo,你最終會在倉庫之間複製貼上程式碼,這會立即分歧,並在幾個月內成為維護噩夢。