TuBrief
구독 채널
비디오
커뮤니티

如何在 Vercel 连接 AWS Aurora Postgres 时 prevent max_connections 错误

TuBrief 편집팀
2026년 7월 21일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

中文한국어EnglishEspañolالعربيةहिन्दीDeutschFrançaisPortuguêsРусскийBahasa Indonesia日本語

관련 영상

Ship 26 NYC - 工作坊 - 使用 Vercel 和 AWS 构建全栈 AI 应用33:34

Ship 26 NYC - 工作坊 - 使用 Vercel 和 AWS 构建全栈 AI 应用

Vercel

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

如何在 Vercel 连接 AWS Aurora Postgres 时 prevent max_connections 错误

大多数 Serverless 基础设施教程仅向您展示点击几次连接按钮的过程。问题出在那之后。一旦部署代码且流量略微增加,数据库连接就会崩溃,管理静态 Access Key 会让您冷汗直流,或者您会收到一张因数据传输费用而高达数百美元的账单。

本文整理了在将 Vercel 前端与 AWS 后端集成时遇到的实务瓶颈及解决方案。

1. Vercel 与 AWS Aurora Postgres 连接时的连接池设置

PostgreSQL 在每次客户端连接时都会启动一个新进程。每个进程会消耗 2MB 到 8MB 以上的内存。由于 Vercel Serverless 函数在收到请求时会无限制地扩展无状态实例,因此仅需几秒钟即可填满 Aurora Postgres 的 max_connections 极限值(100~300个)。

最终会触发 FATAL: sorry, too many clients already 错误,导致 DB CPU 占用率达到 100%,服务挂掉。

必须在 Serverless 函数和 Aurora 之间配置 PgBouncer,并开启事务池(Transaction Pooling)**模式。会话池因为保持 1:1 的连接而毫无帮助,语句池则无法使用多语句事务。事务池仅在执行查询事务期间分配 DB 连接,并在收到 COMMIT 后立即将其返回给连接池。

以下是 pgbouncer.ini 文件的配置标准:

`ini
[pgbouncer]
pool_mode = transaction
max_client_conn = 10000
default_pool_size = 20
reserve_pool_size = 10
max_db_connections = 80

`

  • 通过 pool_mode = transaction 开启以事务为单位的复用。
  • 将 max_client_conn 设置为 10000 左右,并增加 OS 的 ulimit -n 限制。
  • default_pool_size 是每个 DB 用户和 DB 对保持打开的 Aurora 连接数。建议设置为 10 到 20 之间。
  • 将 max_db_connections 严格限制为 80,可以强制控制进入 Aurora 实例的实际连接上限。

在 Vercel Fluid Compute 环境中,多个执行调用会共享全局作用域。因此,必须在模块作用域中声明 DB 驱动程序池。使用 @vercel/functions 包的 attachDatabasePool 可以在函数实例关闭前优雅地清理空闲连接。

`typescript
import { Pool } from 'pg';
import { attachDatabasePool } from '@vercel/functions';

const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 10,
idleTimeoutMillis: 5000,
});

attachDatabasePool(pool);

export default pool;

`

连接字符串也必须按环境进行区分。在本地开发环境(.env.local)中,直接连接到 Aurora 端口(5432)或指向本地 PgBouncer;在生产环境(.env.production)中,附加 PgBouncer 端口(6432)和 pgbouncer=true 参数。

`bash

.env.local (Direct Connection)

DATABASE_URL="postgresql://dbuser:dbpassword@aurora-cluster.us-east-1.rds.amazonaws.com:5432/app_dev?sslmode=require"

.env.production (PgBouncer)

DATABASE_URL="postgresql://dbuser:dbpassword@pgbouncer-proxy.internal:6432/app_prod?sslmode=require&pgbouncer=true"

`

2. 使用 OIDC 代替 Access Key 进行 IAM 权限管理

直接在 Vercel 环境变量中写入 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 是极其危险的。一旦密钥泄露,整个基础设施都将被攻破。如果您还赋予了像 AdministratorAccess 这样的管理员权限,情况将更加严重。

请使用 OIDC(OpenID Connect)。这种方式是将 Vercel 签发的签名 JWT 发送到 AWS STS 的 AssumeRoleWithWebIdentity API,以获取有效期为 1 小时的临时凭证。硬编码的密钥本身将不复存在。

AWS IAM Role 信任关系策略中应仅定义最小权限。

`json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.vercel.com/my-team-slug"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.vercel.com/my-team-slug:aud": "https://vercel.com/my-team-slug",
"oidc.vercel.com/my-team-slug:sub": "owner:my-team-slug:project:my-ai-app:environment:production"
}
}
}
]
}

`

  • 在 IAM Identity Provider 中注册 [oidc.vercel.com/my-team-slug](https://oidc.vercel.com/my-team-slug)。
  • 将 aud 声称限制为 Vercel 团队 URL,以防止其他组织访问。
  • 使用 sub 声称条件精确指定项目名称(my-ai-app)和环境(production)。这是防止混淆代理(Confused Deputy)攻击的核心设置。

权限策略也仅开放所需的资源。以下是仅授予特定 S3 存储桶和 Lambda 函数调用权限的示例。

`json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RestrictedS3BucketAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-production-ai-assets",
"arn:aws:s3:::my-production-ai-assets/*"
]
},
{
"Sid": "RestrictedLambdaInvocation",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:us-east-1:123456789012:function:python-ml-inference-service"
]
}
]
}

`

在 Node.js 代码中,使用 @vercel/oidc-aws-credentials-provider 获取临时凭证。

`typescript
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';
import { awsCredentialsProvider } from '@vercel/oidc-aws-credentials-provider';

const credentials = awsCredentialsProvider({
roleArn: process.env.AWS_ROLE_ARN!,
});

const s3Client = new S3Client({ region: 'us-east-1', credentials });
const lambdaClient = new LambdaClient({ region: 'us-east-1', credentials });

export async function POST(req: Request) {
const body = await req.json();

await s3Client.send(new PutObjectCommand({
Bucket: 'my-production-ai-assets',
Key: inputs/${Date.now()}.json,
Body: JSON.stringify(body),
}));

const lambdaRes = await lambdaClient.send(new InvokeCommand({
FunctionName: 'python-ml-inference-service',
Payload: Buffer.from(JSON.stringify(body)),
}));

return Response.json({
status: 'success',
result: JSON.parse(Buffer.from(lambdaRes.Payload!).toString()),
});
}

`

3. 减少因区域差异导致的 API 延迟时间

如果 Vercel 前端运行在东京 PoP,而 AWS 后端部署在美国东部(us-east-1),则每次请求往返都会增加 150ms 到 250ms 的物理延迟。

对于不经常变更的 API 响应,最好在 Vercel Edge Middleware 层进行缓存,从而避免直接调用后端。

`typescript
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export const config = {
matcher: ['/api/v1/ml-models/:path*'],
};

export function middleware(request: NextRequest) {
const response = NextResponse.next();

response.headers.set(
'Cache-Control',
'public, s-maxage=60, stale-while-revalidate=120'
);
response.headers.set(
'Vercel-CDN-Cache-Control',
's-maxage=300, stale-while-revalidate=600'
);

return response;
}

`

设置 s-maxage=60, stale-while-revalidate=120 后,Edge 缓存将在 60 秒内直接返回响应,而在缓存过期后的 120 秒内会先返回旧版本响应,同时在后台更新缓存。

要连接服务间的链路追踪,必须传播 OpenTelemetry 的 W3C TraceContext 规范(traceparent 请求头)。以下是 Vercel 的配置:

`typescript
// instrumentation.ts
import { registerOTel } from '@vercel/otel';

export function register() {
registerOTel({
serviceName: 'vercel-frontend-service',
instrumentationConfig: {
fetch: {
propagateContextUrls: ['api.my-aws-backend.com', '*.amazonaws.com'],
},
},
});
}

`

在 AWS FastAPI 层同样添加 OpenTelemetry 接收器,即可将前端到后端通过单一 Trace ID 串联起来。

`python
from fastapi import FastAPI
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

provider = TracerProvider()
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="http://otel-collector:4318/v1/traces"))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

app = FastAPI(title="Python ML Service")
FastAPIInstrumentor.instrument_app(app)

@app.get("/api/v1/ml-models/predict")
async def predict():
tracer = trace.get_tracer(name)
with tracer.start_as_current_span("ml_inference_execution"):
return {"status": "completed", "prediction": [0.95, 0.05]}

`

4. 避免数据传输费用与无限制扩展成本

成本事故通常发生在两个地方:Vercel 的 Fast Data Transfer 超额费用(超过 1TB 后每 GB $0.15)和 AWS 的 Data Transfer Out 费用(每 GB $0.09)。再加上流量暴增时 Serverless 函数和 Lambda 开始同时扩展,账单数额将大幅增加。

以下是一个接收 Vercel 支出限额 Webhook 并发送 Slack 通知 API Route 示例。必须通过 HMAC SHA1 签名验证以确保安全。

`typescript
import crypto from 'crypto';

export async function POST(req: Request) {
const payload = await req.text();
const signature = req.headers.get('x-vercel-signature');

const expectedSignature = crypto
.createHmac('sha1', process.env.VERCEL_SPEND_WEBHOOK_SECRET!)
.update(payload)
.digest('hex');

if (signature !== expectedSignature) {
return new Response('Invalid Signature', { status: 401 });
}

const event = JSON.parse(payload);

await fetch(process.env.SLACK_WEBHOOK_URL!, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: Vercel 支出警告:已达到预算限额(${event.payload.spendAmount} USD)。,
}),
});

return new Response('OK', { status: 200 });
}

`

请务必开启以下两个安全防护措施:

  1. 在 Vercel 项目的 Settings > Billing 中开启 Pause production deployment。这样即使达到预算限额导致服务暂停,也能保住您的银行卡余额。
  2. 将 AWS Lambda 的 Reserved Concurrency(预留并发)限制在 50 左右。这可以阻止实例无限扩展并挤压 DB,从而阻断并发产生高额费用的情况。