千人同时在线的 AI 浏览器,后端到底该怎么扛?
AI浏览器 高并发解决方案|附配置文件
随着大模型应用进入企业级落地阶段,“AI浏览器”正在成为一种新的智能入口。它不仅要像传统浏览器一样完成网页访问、账号登录、页面渲染、数据采集、自动化操作,还要叠加大模型推理、Agent任务编排、插件调用、网页理解、RPA自动执行等能力。
但当 AI 浏览器从单用户工具演进为多用户平台时,一个非常现实的问题就会出现:高并发如何支撑?
例如:
- 同时有 1000 个用户打开 AI 浏览器会话;
- 每个用户都在执行网页搜索、网页摘要、表单填写、数据采集;
- 后端需要调度大量浏览器实例;
- 浏览器实例会消耗 CPU、内存、网络和磁盘;
- AI 推理又会带来额外的 Token、请求延迟和队列压力;
- 页面自动化任务可能持续几十秒甚至数分钟。
如果没有合理的架构设计,系统很容易出现:
- 浏览器实例爆满;
- CPU 被 Chromium 进程打满;
- 内存持续上涨直至 OOM;
- WebSocket 连接断开;
- 队列任务堆积;
- AI 接口限流;
- 用户等待时间过长;
- 某个异常页面拖垮整个节点。
本文将从架构设计、任务调度、浏览器池、容器隔离、队列削峰、AI 接口限流、监控告警等角度,系统讲解 AI 浏览器的高并发解决方案,并附上可参考的配置文件。
一、AI浏览器高并发的核心难点
AI浏览器和传统Web服务不同,它的资源消耗更复杂。普通后端服务通常主要消耗 CPU、内存和数据库连接,而 AI 浏览器还要额外维护大量浏览器进程、页面上下文、WebSocket连接、自动化脚本以及AI模型调用链路。
1. 浏览器实例资源消耗高
以 Chromium 为例,一个无头浏览器实例通常会包含多个进程:
- Browser 主进程;
- Renderer 渲染进程;
- GPU 进程;
- Network Service 进程;
- Extension 进程;
- Crashpad 进程。
即使是 headless 模式,一个 Chromium 实例也可能消耗 150MB~500MB 内存。如果页面复杂、JS较多、图片较大,内存可能轻松超过 1GB。
如果不加限制地为每个请求启动一个新浏览器,高并发下服务器会迅速崩溃。
2. 页面任务时间长
AI浏览器任务通常不是瞬时完成的。比如:
- 打开网页;
- 等待页面加载;
- 提取DOM结构;
- 截图;
- 调用大模型分析页面;
- 执行点击、输入、滚动;
- 再次等待页面响应;
- 返回结果。
一个任务可能耗时 10 秒、30 秒甚至几分钟。任务越长,并发占用越严重。
3. AI接口存在限流
AI浏览器通常需要调用大模型接口,例如:
- 页面摘要;
- 网页问答;
- 表格解析;
- 指令规划;
- DOM元素识别;
- 多轮Agent决策。
大模型接口一般会有 TPM、RPM、并发连接数等限制。如果没有限流和队列机制,系统会频繁触发 429 错误。
4. 浏览器自动化存在不确定性
网页结构复杂且不可控,不同网站可能存在:
- 页面加载慢;
- 验证码;
- 反爬机制;
- 弹窗;
- 登录态失效;
- iframe嵌套;
- JS长任务阻塞;
- 第三方资源加载失败。
这意味着单个任务可能卡住,甚至导致浏览器实例异常。如果没有超时、熔断和隔离机制,异常任务会影响整个系统。
二、总体架构设计
一个稳定的 AI 浏览器高并发系统,建议采用分层架构:
用户端
|
| HTTP / WebSocket
v
API Gateway 网关层
|
v
业务服务层
|
+--> 鉴权服务
+--> 会话服务
+--> 任务编排服务
+--> AI调用服务
|
v
消息队列 / 任务队列
|
v
浏览器调度层
|
+--> Browser Pool
+--> Page Context Pool
+--> Worker Node
|
v
容器化浏览器集群
|
+--> Chromium / Playwright / Puppeteer
|
v
监控日志系统
推荐关键组件如下:
| 模块 | 推荐方案 |
|---|---|
| API网关 | Nginx / Kong / APISIX |
| 后端服务 | Node.js / Go / Python FastAPI |
| 浏览器自动化 | Playwright 优先,Puppeteer 次之 |
| 消息队列 | Redis Stream / RabbitMQ / Kafka |
| 任务队列 | BullMQ / Celery / Temporal |
| 缓存 | Redis |
| 数据库 | PostgreSQL / MySQL |
| 容器编排 | Docker Compose / Kubernetes |
| 监控 | Prometheus + Grafana |
| 日志 | Loki / ELK |
| 链路追踪 | OpenTelemetry / Jaeger |
三、高并发解决思路
AI浏览器高并发的核心原则是:不要让请求直接驱动浏览器实例,而是通过队列、池化、限流、隔离和弹性扩容来控制系统压力。
1. 浏览器实例池化
错误做法:
每来一个请求 -> 启动一个 Chromium -> 执行任务 -> 关闭 Chromium
这种方式会导致频繁启动浏览器,成本很高。Chromium启动过程本身就可能耗时数百毫秒到数秒,并且短时间大量启动会造成CPU峰值飙升。
推荐做法:
服务启动时预热N个浏览器实例
请求进入队列
Worker从浏览器池取可用实例
创建新的Browser Context执行任务
任务完成后释放Context
浏览器实例继续复用
Playwright 支持 Browser Context,它比完整浏览器实例更轻量,并且具备较好的隔离性。一个 Browser 可以承载多个 Context,但数量不能无限增加,需要根据机器配置控制。
推荐参数:
单台 8核16G 服务器:
Chromium实例数:4~8
每个Browser最大Context数:4~8
理论并发任务数:16~64
但实际要根据页面复杂度压测决定。
2. 队列削峰
高并发系统中最忌讳的是让所有请求同时打到浏览器执行层。正确做法是将任务放入队列,由Worker按系统承载能力消费。
队列的作用:
- 削峰填谷;
- 控制最大并发;
- 支持失败重试;
- 支持任务优先级;
- 支持延迟任务;
- 支持超时取消;
- 支持任务状态查询。
例如用户提交一个 AI 浏览器任务后,接口立即返回任务ID:
{
"taskId": "task_202501010001",
"status": "queued"
}
前端可以通过轮询或 WebSocket 获取任务进度:
{
"taskId": "task_202501010001",
"status": "running",
"progress": 65,
"message": "正在分析网页内容"
}
这样可以避免HTTP请求长时间阻塞,也能提升系统稳定性。
3. 分级限流
AI浏览器至少需要三层限流:
用户级限流
防止单个用户滥用资源。
例如:
普通用户:最多同时执行2个浏览器任务
高级用户:最多同时执行10个浏览器任务
企业用户:按套餐配置
系统级限流
保护整体服务。
例如:
全局最大排队任务:10000
全局最大运行任务:500
单节点最大运行任务:50
AI模型限流
保护大模型接口不被打爆。
例如:
GPT类模型:每分钟最多500请求
Embedding模型:每分钟最多3000请求
视觉模型:每分钟最多100请求
限流可以使用令牌桶、漏桶或Redis计数器实现。
4. 浏览器任务隔离
高并发环境下,不建议所有任务共享一个浏览器上下文。正确方式是:
- 不同用户使用不同 Context;
- 敏感任务使用独立 Browser;
- 高风险网站任务放入隔离节点;
- 每个任务设置最大执行时间;
- 每个Context任务结束后强制关闭;
- 定期重启Browser进程防止内存泄漏。
推荐隔离策略:
| 任务类型 | 隔离级别 |
|---|---|
| 普通网页摘要 | 共享Browser,独立Context |
| 登录态任务 | 独立Context,持久化UserData |
| 支付/金融页面 | 独立Browser |
| 高风险采集任务 | 独立容器 |
| 未知脚本页面 | 沙箱容器 |
5. 静态资源拦截
很多AI浏览器任务并不需要完整加载页面资源。例如网页摘要、DOM提取、文本采集等任务,不一定需要图片、字体、视频和广告脚本。
可以拦截以下资源:
- image;
- media;
- font;
- stylesheet;
- analytics脚本;
- 广告域名;
- tracking请求。
这样可以显著降低带宽、CPU和内存消耗。
Playwright示例:
await page.route('**/*', async route => {
const request = route.request();
const type = request.resourceType();
if (['image', 'media', 'font'].includes(type)) {
return route.abort();
}
return route.continue();
});
对于需要截图、视觉理解的任务,可以关闭资源拦截或只拦截广告资源。
6. 超时与熔断
每个任务都必须配置超时,否则一个异常页面可能无限占用浏览器资源。
建议配置:
| 操作 | 超时时间 |
|---|---|
| 页面打开 | 15秒 |
| DOM加载 | 10秒 |
| 页面完整加载 | 30秒 |
| AI规划 | 20秒 |
| 单步点击/输入 | 5秒 |
| 总任务时间 | 120秒 |
如果连续出现异常,应触发熔断:
某个域名5分钟内失败率超过70%
暂停该域名任务3分钟
返回降级提示
熔断可以避免某个目标网站异常时拖垮系统。
四、浏览器池设计示例
下面是一个 Node.js + Playwright 的简化浏览器池设计。
const { chromium } = require('playwright');
class BrowserPool {
constructor(options = {}) {
this.maxBrowsers = options.maxBrowsers || 4;
this.maxContextsPerBrowser = options.maxContextsPerBrowser || 6;
this.browsers = [];
this.index = 0;
}
async init() {
for (let i = 0; i < this.maxBrowsers; i++) {
const browser = await chromium.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu',
'--disable-extensions',
'--disable-background-networking',
'--disable-default-apps',
'--disable-sync'
]
});
this.browsers.push({
browser,
activeContexts: 0,
createdAt: Date.now()
});
}
}
async acquireContext() {
const available = this.browsers.find(
item => item.activeContexts < this.maxContextsPerBrowser
);
if (!available) {
throw new Error('NO_AVAILABLE_BROWSER_CONTEXT');
}
available.activeContexts++;
const context = await available.browser.newContext({
viewport: { width: 1365, height: 768 },
userAgent:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120 Safari/537.36'
});
const release = async () => {
try {
await context.close();
} finally {
available.activeContexts--;
}
};
return { context, release };
}
async close() {
for (const item of this.browsers) {
await item.browser.close();
}
}
}
module.exports = BrowserPool;
这个示例仅适合演示,生产环境还需要增加:
- 任务等待队列;
- 浏览器健康检查;
- 浏览器定期重启;
- Context创建失败重试;
- 资源占用统计;
- Worker优雅退出;
- 指标上报;
- 崩溃恢复。
五、任务队列配置示例
如果使用 Node.js,可以采用 BullMQ + Redis 实现任务队列。
1. BullMQ队列配置
const { Queue } = require('bullmq');
const browserTaskQueue = new Queue('ai-browser-task', {
connection: {
host: process.env.REDIS_HOST || '127.0.0.1',
port: Number(process.env.REDIS_PORT || 6379),
password: process.env.REDIS_PASSWORD || undefined
},
defaultJobOptions: {
attempts: 2,
backoff: {
type: 'exponential',
delay: 3000
},
removeOnComplete: 1000,
removeOnFail: 5000,
timeout: 120000
}
});
module.exports = browserTaskQueue;
2. Worker消费配置
const { Worker } = require('bullmq');
const BrowserPool = require('./browser-pool');
const pool = new BrowserPool({
maxBrowsers: Number(process.env.MAX_BROWSERS || 4),
maxContextsPerBrowser: Number(process.env.MAX_CONTEXTS_PER_BROWSER || 6)
});
async function runTask(job) {
const { url, instruction } = job.data;
const { context, release } = await pool.acquireContext();
try {
const page = await context.newPage();
await page.route('**/*', async route => {
const type = route.request().resourceType();
if (['image', 'font', 'media'].includes(type)) {
return route.abort();
}
return route.continue();
});
await page.goto(url, {
waitUntil: 'domcontentloaded',
timeout: 15000
});
const title = await page.title();
const content = await page.locator('body').innerText({ timeout: 10000 });
// 此处可接入AI模型进行摘要、问答、指令规划
return {
title,
instruction,
content: content.slice(0, 5000)
};
} finally {
await release();
}
}
async function start() {
await pool.init();
const worker = new Worker(
'ai-browser-task',
async job => {
return await runTask(job);
},
{
connection: {
host: process.env.REDIS_HOST || '127.0.0.1',
port: Number(process.env.REDIS_PORT || 6379),
password: process.env.REDIS_PASSWORD || undefined
},
concurrency: Number(process.env.WORKER_CONCURRENCY || 16),
lockDuration: 180000
}
);
worker.on('completed', job => {
console.log(`Job ${job.id} completed`);
});
worker.on('failed', (job, err) => {
console.error(`Job ${job?.id} failed`, err);
});
}
start();
这里需要注意:WORKER_CONCURRENCY 不应大于浏览器池可承载的最大 Context 数。比如:
MAX_BROWSERS=4
MAX_CONTEXTS_PER_BROWSER=6
最大Context容量 = 24
WORKER_CONCURRENCY 建议设置为 16~20
保留一定冗余有利于系统稳定。
六、Nginx网关配置文件
AI浏览器通常会使用 WebSocket 推送任务进度,因此 Nginx 必须正确配置 WebSocket 转发、超时时间和上传限制。
下面是一个参考配置:
upstream ai_browser_api {
least_conn;
server api-1:3000 max_fails=3 fail_timeout=30s;
server api-2:3000 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name ai-browser.example.com;
client_max_body_size 20m;
location / {
proxy_pass http://ai_browser_api;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 10s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
}
location /ws/ {
proxy_pass http://ai_browser_api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
如果AI浏览器任务较长,建议不要让HTTP接口一直等待任务结果,而是通过任务ID + WebSocket/轮询返回进度。
七、Docker Compose配置文件
下面给出一个适合中小规模部署的 Docker Compose 示例,包括 API、Worker、Redis、Prometheus 和 Grafana。
version: "3.9"
services:
redis:
image: redis:7-alpine
container_name: ai-browser-redis
command: redis-server --appendonly yes --maxmemory 1gb --maxmemory-policy allkeys-lru
ports:
- "6379:6379"
volumes:
- redis-data:/data
restart: always
api:
image: node:20-bullseye
container_name: ai-browser-api
working_dir: /app
command: sh -c "npm install && npm run start"
volumes:
- ./app:/app
ports:
- "3000:3000"
environment:
NODE_ENV: production
REDIS_HOST: redis
REDIS_PORT: 6379
API_PORT: 3000
MAX_PENDING_TASKS: 10000
depends_on:
- redis
restart: always
worker:
image: mcr.microsoft.com/playwright:v1.42.1-jammy
container_name: ai-browser-worker
working_dir: /app
command: sh -c "npm install && node worker.js"
volumes:
- ./app:/app
environment:
NODE_ENV: production
REDIS_HOST: redis
REDIS_PORT: 6379
MAX_BROWSERS: 4
MAX_CONTEXTS_PER_BROWSER: 6
WORKER_CONCURRENCY: 16
BROWSER_TASK_TIMEOUT: 120000
shm_size: "2gb"
deploy:
resources:
limits:
cpus: "4"
memory: 8G
reservations:
cpus: "2"
memory: 4G
depends_on:
- redis
restart: always
prometheus:
image: prom/prometheus:latest
container_name: ai-browser-prometheus
volumes:
- ./deploy/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
restart: always
grafana:
image: grafana/grafana:latest
container_name: ai-browser-grafana
ports:
- "3001:3000"
volumes:
- grafana-data:/var/lib/grafana
restart: always
volumes:
redis-data:
grafana-data:
重点说明:
shm_size: "2gb"
Chromium 在 Docker 中运行时非常依赖 /dev/shm。如果不设置,默认共享内存可能过小,容易导致页面崩溃或浏览器异常退出。
八、Kubernetes部署配置示例
当并发规模继续上升,例如达到几百到几千个浏览器任务并发,建议迁移到 Kubernetes。
下面是 Worker 的 Deployment 示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-browser-worker
labels:
app: ai-browser-worker
spec:
replicas: 5
selector:
matchLabels:
app: ai-browser-worker
template:
metadata:
labels:
app: ai-browser-worker
spec:
containers:
- name: worker
image: your-registry/ai-browser-worker:latest
imagePullPolicy: Always
env:
- name: REDIS_HOST
value: "redis.default.svc.cluster.local"
- name: REDIS_PORT
value: "6379"
- name: MAX_BROWSERS
value: "4"
- name: MAX_CONTEXTS_PER_BROWSER
value: "6"
- name: WORKER_CONCURRENCY
value: "16"
- name: BROWSER_TASK_TIMEOUT
value: "120000"
resources:
requests:
cpu: "2"
memory: "4Gi"
limits:
cpu: "4"
memory: "8Gi"
volumeMounts:
- mountPath: /dev/shm
name: dshm
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 20"]
volumes:
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 2Gi
terminationGracePeriodSeconds: 60
如果每个 Worker 最大并发为 16,副本数为 5,则理论并发为:
16 × 5 = 80
实际生产中建议保守估算,比如按 60~70% 计算稳定并发容量。
九、HPA自动扩容配置
Kubernetes 中可以根据 CPU、内存或自定义指标扩容。对于 AI浏览器场景,最推荐使用“队列长度”作为扩容指标。
如果暂时没有接入自定义指标,可以先使用 CPU 扩容:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ai-browser-worker-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ai-browser-worker
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65
更理想的扩容策略:
队列等待任务数 > 100,扩容
队列等待时间 P95 > 30秒,扩容
CPU使用率 > 70%,扩容
内存使用率 > 75%,扩容
AI接口429错误率上升,不盲目扩容,而是限流
需要注意,扩容浏览器 Worker 并不能解决所有问题。如果瓶颈在 AI 模型限流或目标网站响应慢,盲目增加 Worker 反而会放大失败率。
十、AI模型调用限流配置
AI浏览器的任务经常要多次调用模型。例如一个网页自动化任务可能包含:
- 根据用户指令生成执行计划;
- 分析页面DOM;
- 判断下一步点击哪个按钮;
- 总结页面结果;
- 生成最终回答。
如果并发任务很多,模型接口会成为关键瓶颈。因此需要单独做模型调用网关。
一个简单的限流配置可以这样设计:
aiModels:
default:
provider: openai-compatible
baseUrl: https://api.example.com/v1
timeoutMs: 30000
retry:
maxAttempts: 2
backoffMs: 1000
limits:
chat:
rpm: 500
tpm: 300000
maxConcurrent: 50
vision:
rpm: 100
tpm: 100000
maxConcurrent: 10
embedding:
rpm: 3000
maxConcurrent: 100
模型调用层建议具备以下能力:
- API Key池;
- 多模型路由;
- 自动降级;
- Token预算;
- 请求缓存;
- 失败重试;
- 超时控制;
- 429退避;
- 调用日志审计。
十一、环境变量配置文件
下面是一个 .env.production 示例:
NODE_ENV=production
API_PORT=3000
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=
MAX_PENDING_TASKS=10000
MAX_RUNNING_TASKS=500
MAX_BROWSERS=4
MAX_CONTEXTS_PER_BROWSER=6
WORKER_CONCURRENCY=16
BROWSER_HEADLESS=true
BROWSER_TASK_TIMEOUT=120000
PAGE_GOTO_TIMEOUT=15000
PAGE_ACTION_TIMEOUT=5000
BLOCK_IMAGE=true
BLOCK_MEDIA=true
BLOCK_FONT=true
BLOCK_ADS=true
AI_BASE_URL=https://api.example.com/v1
AI_API_KEY=replace_with_your_key
AI_MODEL=gpt-4o-mini
AI_TIMEOUT=30000
AI_MAX_CONCURRENT=50
AI_RPM_LIMIT=500
LOG_LEVEL=info
METRICS_PORT=9100
生产环境中不建议将密钥直接写入 .env 文件,应使用:
- Kubernetes Secret;
- Docker Secret;
- Vault;
- 云厂商密钥管理服务。
十二、Prometheus监控配置
AI浏览器系统必须做监控,否则无法判断瓶颈在哪里。
建议监控以下指标:
| 指标 | 说明 |
|---|---|
| queue_waiting_jobs | 队列等待任务数 |
| queue_active_jobs | 正在执行任务数 |
| task_success_total | 成功任务数 |
| task_failed_total | 失败任务数 |
| task_duration_p95 | 任务P95耗时 |
| browser_active_contexts | 活跃Context数量 |
| browser_crash_total | 浏览器崩溃次数 |
| node_cpu_usage | 节点CPU使用率 |
| node_memory_usage | 节点内存使用率 |
| ai_request_total | AI请求总数 |
| ai_429_total | AI限流次数 |
| ai_latency_p95 | AI调用P95延迟 |
Prometheus配置示例:
global:
scrape_interval: 15s
scrape_configs:
- job_name: "ai-browser-api"
static_configs:
- targets: ["api:9100"]
- job_name: "ai-browser-worker"
static_configs:
- targets: ["worker:9100"]
- job_name: "redis"
static_configs:
- targets: ["redis-exporter:9121"]
告警规则示例:
groups:
- name: ai-browser-alerts
rules:
- alert: HighQueueBacklog
expr: queue_waiting_jobs > 1000
for: 5m
labels:
severity: warning
annotations:
summary: "AI浏览器任务队列积压严重"
description: "等待任务数超过1000,持续5分钟"
- alert: BrowserCrashTooMany
expr: increase(browser_crash_total[5m]) > 10
for: 2m
labels:
severity: critical
annotations:
summary: "浏览器崩溃次数过多"
description: "5分钟内浏览器崩溃超过10次"
- alert: AIModelRateLimited
expr: increase(ai_429_total[5m]) > 20
for: 2m
labels:
severity: warning
annotations:
summary: "AI模型接口触发限流"
description: "5分钟内AI接口429错误超过20次"
十三、性能压测建议
上线前必须压测。AI浏览器压测不能只看QPS,还要关注任务完成率和资源曲线。
建议压测维度:
- 并发任务数:10、50、100、300、500逐步增加;
- 任务类型:网页摘要、截图、自动点击、登录态任务;
- 页面复杂度:静态页面、SPA页面、重资源页面;
- AI调用次数:无AI、1次AI、多轮AI;
- 任务时长:短任务、中任务、长任务;
- 异常页面比例:模拟10%超时页面;
- 模型限流场景:模拟429和网络错误。
核心观察指标:
任务成功率 >= 99%
P95任务耗时可接受
CPU长期低于75%
内存无持续泄漏
浏览器崩溃率低
队列等待时间可控
AI接口错误率可控
如果压测发现内存持续上涨,需要检查:
- Context是否关闭;
- Page是否关闭;
- 下载文件是否清理;
- 截图缓存是否释放;
- 是否存在全局变量持有页面对象;
- Browser是否定期重启。
十四、生产最佳实践
1. Worker定期重启
浏览器进程长时间运行后可能出现内存碎片或泄漏,建议定期重启:
每个Browser执行500个任务后重启
或每运行2小时重启
或内存超过阈值重启
2. 任务分级队列
不同任务消耗不同,建议拆分队列:
light-task:网页文本提取、摘要
normal-task:自动点击、表单填写
heavy-task:截图、视觉识别、长流程Agent
isolated-task:高风险网站、登录态任务
不同队列配置不同并发,避免重任务阻塞轻任务。
3. 登录态单独管理
对于需要账号登录的网站,不建议在任务结束后简单销毁所有状态。可以使用加密存储的 storageState:
await context.storageState({ path: 'state/user-123.json' });
但必须注意:
- 用户隔离;
- 文件加密;
- 定期失效;
- 权限控制;
- 审计日志。
4. 降级策略
当系统压力过高时,可以降级:
- 只返回文本摘要,不截图;
- 减少AI多轮规划次数;
- 禁止重任务进入;
- 暂停低优先级用户;
- 使用缓存结果;
- 延迟执行批量任务。
5. 安全策略
AI浏览器可能访问外部网页,必须注意安全:
- 禁止访问内网地址;
- 防止 SSRF;
- 限制下载文件类型;
- 禁止执行本地命令;
- 容器只读文件系统;
- 限制网络出口;
- 对用户输入进行审计;
- 浏览器运行在非root用户下。
十五、推荐容量规划
假设单个 Worker 节点配置为:
CPU:4核
内存:8GB
MAX_BROWSERS=4
MAX_CONTEXTS_PER_BROWSER=6
WORKER_CONCURRENCY=16
保守估算:
单节点稳定并发:12~16个任务
10个节点稳定并发:120~160个任务
30个节点稳定并发:360~480个任务
如果任务较轻,例如只做DOM提取和文本摘要,单节点可以更高;如果任务包含截图、视觉模型、复杂SPA页面,单节点并发应降低。
容量规划公式可以简化为:
稳定并发 = Worker节点数 × 单节点Worker并发 × 稳定系数
其中稳定系数建议取:
轻任务:0.8
普通任务:0.6
重任务:0.4
结语
AI浏览器的高并发本质上不是简单地“多开几个浏览器”,而是一套完整的工程体系。它需要在浏览器池、任务队列、资源隔离、AI限流、容器调度、监控告警、安全控制之间取得平衡。
一个可靠的生产级方案应当具备以下能力:
- 浏览器实例池化;
- Context级别隔离;
- 任务队列削峰;
- 用户级、系统级、模型级限流;
- 超时、重试、熔断;
- Docker/Kubernetes容器化部署;
- Prometheus监控与告警;
- 基于队列长度的自动扩容;
- 清晰的降级策略;
- 严格的安全边界。
如果是中小规模业务,可以先使用 Docker Compose + Redis + BullMQ + Playwright 搭建基础版本;如果并发规模提升到数百甚至上千,则建议迁移到 Kubernetes,并引入 HPA、任务分级队列、独立模型网关和更完善的监控体系。
真正稳定的 AI 浏览器系统,不是追求单机极限并发,而是追求可控、可观测、可扩展、可恢复。只要架构设计合理,即使面对复杂网页、大量用户和多轮AI调用,也能保持系统稳定运行。