部署 Mastra Worker
将 Mastra Worker 作为独立进程运行,以便单独扩缩编排、调度和后台任务,而不受 API 影响。本指南逐步介绍如何使用 Docker Compose 或 Kubernetes 进行完全拆分式部署。
本指南介绍如何将 Worker 拆分到各自容器中。如果只需让 Worker 与 API 一起在进程内运行,请参阅 Worker,无需额外设置。
开始之前开始之前的直接链接
你需要:
- 一个 Mastra 应用
- Docker 和 Docker Compose,或一个带有
kubectl的 Kubernetes 集群 - 一个分布式 PubSub 后端:用于
RedisStreamsPubSub的 Redis,或用于GoogleCloudPubSub的 Google Cloud 项目 - 一个所有容器均可访问的共享数据库。完整列表请参阅支持的 Storage 后端。
默认内存 PubSub 无法跨进程传递事件。在将 Worker 拆分到独立容器之前,必须配置分布式 PubSub 后端。
配置共享基础设施配置共享基础设施的直接链接
将 Mastra 实例指向分布式 PubSub 后端和共享数据库。使用环境变量,使同一个镜像可以在每个容器中运行。
- Redis Streams + PostgreSQL
- Google Cloud Pub/Sub + LibSQL
import { Mastra } from '@mastra/core/mastra'
import { RedisStreamsPubSub } from '@mastra/redis-streams'
import { PostgresStore } from '@mastra/pg'
export const mastra = new Mastra({
storage: new PostgresStore({
connectionString: process.env.DATABASE_URL!,
}),
pubsub: new RedisStreamsPubSub({
url: process.env.REDIS_URL!,
}),
})
import { Mastra } from '@mastra/core/mastra'
import { GoogleCloudPubSub } from '@mastra/google-cloud-pubsub'
import { LibSQLStore } from '@mastra/libsql'
export const mastra = new Mastra({
storage: new LibSQLStore({
url: process.env.DATABASE_URL!,
}),
pubsub: new GoogleCloudPubSub({
projectId: process.env.GCP_PROJECT_ID!,
}),
})
可以使用任意受支持的 Storage 后端。请将 Storage 适配器替换为你偏好的数据库。
部署部署的直接链接
构建 Mastra 应用。输出会在每个容器中运行。
mastra build这会生成自包含的
.mastra/output/目录。有关构建输出的详情,请参阅部署 Mastra Server。创建 Dockerfile,复制预先构建的输出并安装生产依赖:
app/DockerfileFROM node:22-alpineWORKDIR /appCOPY .mastra/output/package.json .mastra/output/.npmrc* ./RUN npm install --omit=devCOPY .mastra/output/ .EXPOSE 4111CMD ["node", "index.mjs"]定义完全拆分的拓扑。该设置运行六项服务:一个数据库、一个 PubSub 后端、API Server 和三个 Worker。每个 Worker 都运行相同镜像,并通过不同的
MASTRA_WORKERS值控制启动哪种 Worker。API 设置
MASTRA_WORKERS: "false"以禁用所有事件处理。编排 Worker 设置MASTRA_STEP_EXECUTION_URL,将步骤执行请求指向 API 的内部 URL。详情请参阅步骤执行 URL。所有服务共享一个
MASTRA_WORKER_AUTH_TOKEN。Worker 在发往 API 的请求中包含该 token,使 API 可以验证调用方是否为受信任的内部服务。详情请参阅 Worker 身份验证。- Docker Compose
- Kubernetes
docker-compose.ymlservices:postgres:image: postgres:16-alpineenvironment:POSTGRES_USER: mastraPOSTGRES_PASSWORD: ${POSTGRES_PASSWORD}POSTGRES_DB: mastraports:- '5432:5432'volumes:- pgdata:/var/lib/postgresql/datahealthcheck:test: ['CMD-SHELL', 'pg_isready -U mastra']interval: 5stimeout: 3sretries: 5redis:image: redis:7-alpineports:- '6379:6379'healthcheck:test: ['CMD', 'redis-cli', 'ping']interval: 5stimeout: 3sretries: 5api:build: ./appports:- '4111:4111'environment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: 'false'MASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:postgres:condition: service_healthyredis:condition: service_healthyhealthcheck:test: ['CMD', 'wget', '-qO-', 'http://localhost:4111/api/agents']interval: 5stimeout: 3sretries: 5orchestration-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: orchestrationMASTRA_STEP_EXECUTION_URL: http://api:4111/apiMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthyscheduler-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: schedulerMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthybackground-task-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: backgroundTasksMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthyvolumes:pgdata:在
docker-compose.yml旁创建.env文件:.envPOSTGRES_PASSWORD=your-secure-passwordMASTRA_WORKER_AUTH_TOKEN=your-shared-secret-token备注请设置应用所需的其他环境变量(例如模型 Provider API Key)。
创建 namespace 和包含连接字符串的 Secret:
k8s/namespace.yamlapiVersion: v1kind: Namespacemetadata:name: mastra-workerskubectl apply -f k8s/namespace.yamlkubectl create secret generic mastra-secrets -n mastra-workers \--from-literal=POSTGRES_PASSWORD='your-password' \--from-literal=DATABASE_URL='postgresql://mastra:your-password@postgres:5432/mastra' \--from-literal=REDIS_URL='redis://redis:6379' \--from-literal=MASTRA_WORKER_AUTH_TOKEN='your-shared-token'备注将应用所需的其他环境变量(例如模型 Provider API Key)添加到 Secret,或添加为额外的
--from-literal条目。构建 Docker 镜像并将其推送到集群可以从中拉取镜像的 Registry:
docker build -t your-registry/mastra-workers:latest ./appdocker push your-registry/mastra-workers:latest为数据库、PubSub 后端、API 和三个 Worker 应用 Deployment 和 Service。以下示例使用集群内 Postgres 和 Redis。在生产环境中,请使用托管服务(例如 Amazon RDS、Cloud SQL、ElastiCache、Memorystore)。
k8s/postgres.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: postgresnamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: postgrestemplate:metadata:labels:app: postgresspec:containers:- name: postgresimage: postgres:16-alpineports:- containerPort: 5432env:- name: POSTGRES_USERvalue: mastra- name: POSTGRES_PASSWORDvalueFrom:secretKeyRef:name: mastra-secretskey: POSTGRES_PASSWORD- name: POSTGRES_DBvalue: mastravolumeMounts:- name: pgdatamountPath: /var/lib/postgresql/datavolumes:- name: pgdataemptyDir: {}---apiVersion: v1kind: Servicemetadata:name: postgresnamespace: mastra-workersspec:selector:app: postgresports:- port: 5432targetPort: 5432警告上述 Postgres 示例使用
emptyDir进行存储,这意味着 Pod 重启时数据会丢失。在生产环境中,请将其替换为PersistentVolumeClaim或使用托管数据库服务。k8s/redis.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: redisnamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- name: redisimage: redis:7-alpineargs: ['--appendonly', 'yes']ports:- containerPort: 6379---apiVersion: v1kind: Servicemetadata:name: redisnamespace: mastra-workersspec:selector:app: redisports:- port: 6379targetPort: 6379k8s/api.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: apinamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: apitemplate:metadata:labels:app: apispec:containers:- name: apiimage: your-registry/mastra-workers:latestports:- containerPort: 4111env:- name: MASTRA_WORKERSvalue: 'false'envFrom:- secretRef:name: mastra-secretsreadinessProbe:httpGet:path: /api/agentsport: 4111initialDelaySeconds: 10periodSeconds: 5livenessProbe:httpGet:path: /api/agentsport: 4111initialDelaySeconds: 15periodSeconds: 10resources:requests:cpu: 500mmemory: 512Mi---apiVersion: v1kind: Servicemetadata:name: apinamespace: mastra-workersspec:selector:app: apiports:- port: 4111targetPort: 4111k8s/orchestration-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: orchestration-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: orchestration-workertemplate:metadata:labels:app: orchestration-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: orchestration- name: MASTRA_STEP_EXECUTION_URLvalue: http://api:4111/apienvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Mik8s/scheduler-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: scheduler-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: scheduler-workertemplate:metadata:labels:app: scheduler-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: schedulerenvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Mik8s/background-task-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: background-task-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: background-task-workertemplate:metadata:labels:app: background-task-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: backgroundTasksenvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Mi应用所有 manifest,等待 API 就绪:
kubectl apply -f k8s/kubectl wait -n mastra-workers --for=condition=ready pod -l app=api --timeout=90skubectl wait -n mastra-workers --for=condition=ready pod -l app=orchestration-worker --timeout=60skubectl wait -n mastra-workers --for=condition=ready pod -l app=scheduler-worker --timeout=60skubectl wait -n mastra-workers --for=condition=ready pod -l app=background-task-worker --timeout=60s验证该堆栈是否正在运行且 API 能够响应:
- Docker Compose
- Kubernetes
docker compose up -ddocker compose pscurl http://localhost:4111/api/agentskubectl get pods -n mastra-workerskubectl port-forward -n mastra-workers svc/api 4111:4111在另一个终端中:
curl http://localhost:4111/api/agents如果返回 Agent 的 JSON 列表,则表示 API 和 Worker 正在运行。
步骤执行 URL步骤执行 URL的直接链接
在完全拆分的部署中,编排 Worker 与 API 运行在不同容器中。处理 Workflow 事件时,它会通过 HTTP 将步骤执行委托给 API。
将 MASTRA_STEP_EXECUTION_URL 设置为 API 的内部 URL,并包含 /api 前缀:
MASTRA_STEP_EXECUTION_URL=http://api:4111/api
编排 Worker 会针对每个步骤向 ${MASTRA_STEP_EXECUTION_URL}/workflows/:workflowId/runs/:runId/steps/execute 发送 POST 请求。API 解析 Workflow 并在本地执行该步骤。
如果未设置该变量,编排 Worker 会尝试在进程内执行步骤。Worker 与 API 一起运行时,这种方式有效;但在拆分式部署中,Worker 无法访问完整 Mastra Runtime,因此会失败。
扩缩扩缩的直接链接
编排 Worker 和后台任务 Worker 可以安全地水平扩缩。PubSub 消费者组会在实例之间分发事件,因此每个事件只会处理一次:
- Docker Compose
- Kubernetes
docker compose up -d --scale orchestration-worker=3
docker compose up -d --scale background-task-worker=2
kubectl scale deployment/orchestration-worker -n mastra-workers --replicas=3
kubectl scale deployment/background-task-worker -n mastra-workers --replicas=2
如需自动扩缩,请添加 HorizontalPodAutoscaler:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: orchestration-worker
namespace: mastra-workers
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: orchestration-worker
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
基于 CPU 的自动扩缩要求集群中运行 metrics-server。GKE、EKS 和 AKS 等托管集群默认包含该组件。
API 也可以在负载均衡器后水平扩缩。
**请勿扩缩 Scheduler Worker。**必须只运行一个实例。多个 Scheduler 轮询同一个 Storage 时,会针对同一个 Schedule 触发重复事件。
崩溃恢复崩溃恢复的直接链接
Worker 可以从崩溃中恢复,因为分布式 PubSub 后端会持久化未确认事件:
- 编排 Worker:待处理事件保留在 PubSub 后端中。Worker 重启时,会从中断处继续处理。
- Scheduler Worker:不会永久错过任何事件。重启时,Scheduler 会根据当前时间而非中断位置计算下次触发时间。
- 步骤执行期间的 API:编排 Worker 的 HTTP 请求失败。事件会被 nack,并在下次尝试时重新传递。
如果 API 在步骤执行期间崩溃(例如在 sleep 过程中),该步骤的工作会丢失。Workflow 运行可能会一直停留在 running 状态。Mastra 目前尚不支持在这种情况下基于超时自动恢复。
相关内容相关内容的直接链接
- Worker:Worker 的定义及适用场景
- Worker 身份验证:保护 Worker 到 API 的通信
- Worker Reference:所有 Worker 类型的配置详情
- CLI Reference:
mastra worker build和mastra worker start - PubSub:事件传递后端
- 部署 Mastra Server:构建输出和 Server 配置
- 将 Mastra 部署到 Kubernetes:使用持久化 Agent 进行多 Pod 部署