多租户与多区域
本教程共 42 篇 · 第 42 篇 · 更新于 2026-07-30 · 约 6 分钟阅读
42. 多租户与多区域
本节目标:理解 Next.js 多区域(Multi-Zones)微前端架构,学会构建多租户应用和跨应用路由。
多区域(Multi-Zones)
多区域是 Next.js 实现微前端的方式。把一个大应用拆成多个独立的小应用,每个应用负责一部分路径,但共享同一个域名。
适用场景
/blog/* -> 博客应用(独立团队维护)
/dashboard/* -> 后台应用(独立团队维护)
/* -> 主站应用
拆分的好处:
- 构建更快:每个应用体积小,构建时间短
- 独立部署:各团队自主发版,互不影响
- 技术灵活:不同区域可以用不同框架
导航行为
- 区域内导航:软导航(不刷新页面)
- 跨区导航:硬导航(整页刷新)
经常一起访问的页面应该放在同一个区域,避免频繁硬导航。
定义区域
每个区域就是一个普通的 Next.js 应用,但需要配置 assetPrefix 避免资源冲突:
// 博客应用的 next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
assetPrefix: '/blog-static',
}
export default nextConfig
静态资源会发布在 /blog-static/_next/...,不会和其他区域冲突。
主站应用(处理兜底路径)不需要 assetPrefix。
路由配置
用 rewrites 路由
在一个 Next.js 应用中配置 rewrite 规则,把请求转发到对应的区域:
// 主站应用的 next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
async rewrites() {
return [
{
source: '/blog',
destination: `${process.env.BLOG_DOMAIN}/blog`,
},
{
source: '/blog/:path+',
destination: `${process.env.BLOG_DOMAIN}/blog/:path+`,
},
{
source: '/blog-static/:path+',
destination: `${process.env.BLOG_DOMAIN}/blog-static/:path+`,
},
]
},
}
export default nextConfig
注意:URL 路径在每个区域内必须唯一。两个区域不能同时服务
/blog。
用代理路由
也可以用 Nginx、Varnish 等 HTTP 代理做路由。代理方式更灵活,比如可以根据 feature flag 动态决定路由目标:
export async function proxy(request) {
const { pathname, search } = request.nextUrl
if (pathname === '/your-path' && myFeatureFlag.isEnabled()) {
return NextResponse.rewrite(`${rewriteDomain}${pathname}${search}`)
}
}
区域间链接
跨区域的链接必须用 <a> 标签,不能用 <Link> 组件。因为 <Link> 会尝试做软导航和预加载,跨区时无效:
// 错误:跨区用 Link 会失效
<Link href="/dashboard">控制台</Link>
// 正确:跨区用 a 标签
<a href="/dashboard">控制台</a>
区域内导航还是推荐用 <Link>,享受软导航的性能优势。
代码共享
Monorepo
把多个区域放在同一个 monorepo 里,方便共享代码:
apps/
├── main/ # 主站
├── blog/ # 博客
└── dashboard/ # 后台
packages/
└── shared/ # 共享组件库
NPM 包
如果区域在不同仓库,可以用公共或私有 NPM 包共享代码。
Server Actions 跨域
多区域部署时,Server Actions 需要额外配置 allowedOrigins:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
serverActions: {
allowedOrigins: ['your-production-domain.com'],
},
},
}
export default nextConfig
因为用户看到的域名可能对应多个后端应用,需要明确允许跨域调用。
多租户架构
多租户是指一个应用为多个客户(租户)服务,每个租户有独立的数据和配置。
官方示例
Next.js 提供了 platforms-starter-kit 模板,展示了推荐的多租户架构。
常见实现方式
基于子域名:
tenant1.example.com
tenant2.example.com
基于路径:
example.com/tenant1
example.com/tenant2
基于自定义域名:
tenant1.com -> 指向你的应用
tenant2.com -> 指向你的应用
租户识别
在 proxy.ts 中识别租户:
export function proxy(request: NextRequest) {
const hostname = request.headers.get('host')
// 根据 hostname 查询租户信息
const tenant = await getTenantByHost(hostname)
// 把租户信息存入请求头,供后续使用
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-tenant-id', tenant.id)
return NextResponse.next({
request: { headers: requestHeaders },
})
}
数据隔离
// 所有查询都带上租户 ID
export async function getPosts(tenantId: string) {
return db.select().from(posts).where(eq(posts.tenantId, tenantId))
}
租户级缓存
import { unstable_cache } from 'next/cache'
export const getCachedPosts = unstable_cache(
async (tenantId: string) => {
return await getPosts(tenantId)
},
['posts'],
{
tags: (tenantId) => [`posts-${tenantId}`],
}
)
最佳实践
- 按业务边界拆分区域:不同业务模块独立部署
- 区域内高内聚:频繁互动的页面放一起
- 共享登录态:用顶层 domain 的 cookie 共享认证
- 统一设计系统:跨区域的组件库保持一致
- 监控每个区域:独立追踪各区域的性能和错误
注意事项
- SEO 影响:跨区硬导航对 SEO 有一定影响,重要页面做好 SSR
- 首屏加载:每个区域首次访问需要完整加载
- 会话共享:确保 cookie domain 设置正确
- 错误隔离:一个区域的错误不应影响其他区域
多区域和多租户是大型应用的演进方向。早期不需要过度设计,但了解这些方案能在业务增长时做出正确的选择。