跳到主要内容
非官方简体中文翻译,内容版权归 Mastra 所有,遵循 Apache-2.0 许可。

Workers

beta

在 API 稳定之前,可能会在不提升主版本号的情况下发生破坏性变更。当前差距请参阅已知限制。

Workers 在请求-响应周期之外处理后台工作。工作流步骤执行、基于 cron 的调度以及长时间运行的工具调用都在 workers 中运行,从而保持 API 响应迅速。

默认情况下,workers 与 API 在同一进程中运行。对于生产负载,你可以将它们拆分到单独的进程或容器中,并独立扩展每个部分。

何时使用 workers
何时使用 workers的直接链接

以下任一情况适用时,workers 就很重要:

  • 工作流步骤耗时超过几秒钟,且不应阻塞 API 响应
  • 你需要事件持久性,使正在处理的工作在进程重启后继续存活
  • 系统不同部分需要独立扩展(例如,增加编排容量而不增加 API 实例)
  • 后台工具调用应在专用计算资源上运行

如果你的应用流量较轻且工作流完成很快,默认的进程内设置就足够了。在需要之前无需引入 worker 基础设施。

Worker 类型
Worker 类型的直接链接

Mastra 有三种内置 worker 类型。每种负责特定类型的后台处理。

编排 worker
编排 worker的直接链接

该 worker 订阅 PubSub 总线上的工作流事件并执行工作流步骤。它会处理每个 workflow.start 和生命周期事件,以及每次步骤转换。

在拆分部署中,编排 worker 从分布式 PubSub 后端拉取事件,并通过 HTTP 将步骤执行委托回 API。在进程内模式下,它直接运行步骤。

编排 worker 需要支持拉取模式的 PubSub 后端(例如 RedisStreamsPubSub、ValkeyStreamsPubSub 或 GoogleCloudPubSub)。

调度 worker
调度 worker的直接链接

轮询存储以查找到期的 cron 调度,并为每次触发发布 workflow.start 事件。它只是生产者,即它为编排 worker 创建待处理的工作:

  • 拆分进程:定时工作流在事件驱动引擎上运行,编排 worker 逐步运行每次触发。
  • 进程内模式:定时工作流在默认引擎上运行。同一进程中的编排 worker 在进程内运行每次触发,与直接调用 run.start() 的方式相同。

调度器会自动读取工作流定义中的声明式 schedule 字段。如何声明调度请参阅定时工作流。

调度器只有在存在调度时才会轮询存储。启动时,没有声明任何调度的进程会执行一次 listSchedules() 检查。如果该检查没有找到记录,轮询循环就不会启动,因此空闲部署不会产生重复的调度器查询,并且可以缩减到零。

当在运行时创建调度时,Mastra 会在 PubSub 后端发布唤醒事件。任何运行默认 worker 集的进程都会响应并启动其调度器,独立 worker 正是通过这种方式发现 API 进程创建的调度。这要求两个进程共享同一个 PubSub 后端。

要在启动时无论是否存在调度都进行轮询(例如,你的进程不共享 PubSub 后端时),请在 worker 上设置 scheduler: { enabled: true },或使用 MASTRA_WORKERS=scheduler 运行它。

不要运行多个调度器实例。 多个调度器轮询同一存储会导致同一调度触发重复事件。

后台任务 worker
后台任务 worker的直接链接

执行标记为 background: { enabled: true } 的 agent 工具调用。当 agent 调用后台工具时,API 会将任务分派给该 worker,而不是阻塞响应流。

后台任务 worker 通过 PubSub 总线管理并发限制、任务生命周期和结果传递。

Workers 的运行方式
Workers 的运行方式的直接链接

进程内模式(默认)
进程内模式(默认)的直接链接

无需任何配置,Mastra 会在 API 进程内运行 workers。事件通过内存中的 PubSub 流动,所有内容共享单个 Node.js 运行时。

src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra'

export const mastra = new Mastra({
// Workers run in-process by default.
// No pubsub or worker config needed.
})

mastra build 生成的服务器会自动启动这些 workers。如果你改用服务端适配器,请在服务器开始监听后添加对 mastra.startWorkers() 的调用。参见启动后台工作进程。

此设置除了存储适配器之外不需要任何外部基础设施。它无法在进程崩溃后继续存活,你也无法单独扩展各个组件。

拆分进程
拆分进程的直接链接

要在独立进程中运行 workers,请配置分布式 PubSub 后端,并使用 MASTRA_WORKERS 环境变量控制每个进程中启动哪些 workers。

src/mastra/index.ts
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!,
}),
})

任何支持的存储后端都可以使用。将存储适配器替换为你偏好的数据库即可。

在多个容器中运行同一个构建产物,每个容器使用不同的 MASTRA_WORKERS 值,以控制每个进程中启动哪个 worker。

拆分部署需要分布式 PubSub 后端(RedisStreamsPubSub、ValkeyStreamsPubSub 或 GoogleCloudPubSub)、共享的存储后端,以及编排 worker 与 API 之间的网络连接。

选择 workers
选择 workers的直接链接

设置 MASTRA_WORKERS 以控制每个进程中运行哪些 workers:

值行为
false禁用所有 workers。在完全拆分部署中用于 API 进程。
orchestration启动编排 worker。
scheduler启动调度 worker。
backgroundTasks启动后台任务 worker。
orchestration,backgroundTasks通过逗号分隔的允许列表启动多个 workers。

你也可以向 CLI 传入 worker 名称。该命令会在生成的进程中设置 MASTRA_WORKERS:

mastra worker start orchestration

在拆分部署的每个进程上设置 MASTRA_WORKERS,包括在 API 进程上设为 false。任何值都会将声明了 schedule 的工作流切换到事件驱动引擎,并且每个进程都必须在同一引擎上运行这些工作流。参见定时工作流。不带 worker 名称的 mastra worker start 不会设置 MASTRA_WORKERS,因此请传入名称或在进程环境中设置该变量。

网络架构
网络架构的直接链接

Workers 是内部基础设施。它们不暴露给最终用户,也不需要自己的子域名或公共 URL,包括入站 HTTP 路由。

在拆分部署中:

  • API 服务器是唯一面向公众的进程:它处理所有客户端 HTTP 请求。这些请求包括 REST 端点和 agent 交互,以及工作流触发器和自定义路由。
  • Workers 不处理客户端流量:它们从分布式 PubSub 后端拉取事件,并对共享存储数据库进行读写。每个 worker 进程还会监听 PORT(默认 4111)以进行内部健康检查。/health 报告就绪状态,/config 向授权调用方返回 worker 配置。请将此端口保持在私有网络中。
  • 编排 worker 在内部调用 API:它使用 MASTRA_STEP_EXECUTION_URL 通过容器网络向 API 发送步骤执行请求。这是内部服务间通信,不是公共端点。

所有三种 worker 类型(编排、调度、后台任务)都位于 API 之后的私有网络中。它们共享对 PubSub 后端和存储数据库的访问权限,但永远不会直接接收客户端流量。worker 相关功能的 HTTP 路由在 API 服务器上运行,而不是在 worker 进程中。一个例子是为语音集成创建 Token。

部署拆分的 workers
部署拆分的 workers的直接链接

构建 API 和 worker 产物:

mastra build
mastra worker build --output-dir .mastra/worker

mastra build 在 .mastra/output/ 中创建 API 产物。mastra worker build 在 .mastra/worker/ 中创建 worker 产物。以下 Dockerfile 可接受任一目录:

Dockerfile
FROM node:22-alpine

ARG MASTRA_OUTPUT=.mastra/output

WORKDIR /app

COPY ${MASTRA_OUTPUT}/package.json ${MASTRA_OUTPUT}/.npmrc* ./
RUN npm install --omit=dev

COPY ${MASTRA_OUTPUT}/ .

EXPOSE 4111
CMD ["node", "index.mjs"]

有关构建输出的更多信息,请参阅部署 Mastra 服务器。

Docker Compose
Docker Compose的直接链接

以下配置运行 PostgreSQL、Redis、API,以及每种 worker 类型一个进程。每个进程都使用共享基础设施,worker 进程使用 worker 产物。

docker-compose.yml
x-worker: &worker
build:
context: .
args:
MASTRA_OUTPUT: .mastra/worker

x-mastra-environment: &shared-environment
DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastra
REDIS_URL: redis://redis:6379

services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: mastra
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: mastra
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U mastra']
interval: 5s
timeout: 3s
retries: 5

redis:
image: redis:7-alpine
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 5s
timeout: 3s
retries: 5

api:
build:
context: .
args:
MASTRA_OUTPUT: .mastra/output
ports:
- '4111:4111'
environment:
<<: *shared-environment
WORKER_TOKEN: ${WORKER_TOKEN}
MASTRA_WORKERS: 'false'
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ['CMD', 'wget', '-qO-', 'http://localhost:4111/api/agents']
interval: 5s
timeout: 3s
retries: 5

orchestration-worker:
<<: *worker
environment:
<<: *shared-environment
MASTRA_WORKERS: orchestration
MASTRA_STEP_EXECUTION_URL: http://api:4111/api
MASTRA_WORKER_AUTH_TOKEN: ${WORKER_TOKEN}
depends_on:
api:
condition: service_healthy

scheduler-worker:
<<: *worker
environment:
<<: *shared-environment
MASTRA_WORKERS: scheduler
depends_on:
api:
condition: service_healthy

background-task-worker:
<<: *worker
environment:
<<: *shared-environment
MASTRA_WORKERS: backgroundTasks
depends_on:
api:
condition: service_healthy

volumes:
pgdata:

在 docker-compose.yml 旁边设置机密,以及应用所需的任何模型提供方凭据:

.env
POSTGRES_PASSWORD=your-secure-password
WORKER_TOKEN=your-shared-secret-token

在暴露部署之前,配置 API 认证提供方以接受 WORKER_TOKEN。编排 worker 通过 MASTRA_WORKER_AUTH_TOKEN 发送相同的值。调度和后台任务 workers 在此拉取式拓扑中不调用步骤执行端点,因此不需要该变量。

启动栈并验证容器和 API 可用:

docker compose up -d
docker compose ps
curl http://localhost:4111/api/agents

Kubernetes
Kubernetes的直接链接

Helm

在 Kubernetes 上,mastra-projects Helm chart 会为你渲染这些 Deployment,workers 与服务器使用相同的镜像和环境。它还会拒绝安装会导致每个 worker 运行两次的组合。下面的清单用于手动编写。

为 API、编排 worker、调度 worker 和后台任务 worker 创建单独的 Deployment。每个 Deployment 使用相同的镜像和 Secret,仅在各容器上直接设置角色特定的环境变量。

编排 worker 的 Deployment 具有以下形式:

k8s/orchestration-worker.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: orchestration-worker
spec:
replicas: 1
selector:
matchLabels:
app: orchestration-worker
template:
metadata:
labels:
app: orchestration-worker
spec:
containers:
- name: worker
image: your-registry/mastra-workers:latest
env:
- name: MASTRA_WORKERS
value: orchestration
- name: MASTRA_STEP_EXECUTION_URL
value: http://api:4111/api
envFrom:
- secretRef:
name: mastra-secrets
resources:
requests:
cpu: 250m
memory: 256Mi

其他 worker Deployment 使用 MASTRA_WORKERS: scheduler 和 MASTRA_WORKERS: backgroundTasks。在 API Deployment 上设置 MASTRA_WORKERS: 'false',并通过 Service 暴露 API。让每个进程都能访问相同的数据库和 PubSub 后端。使用 worker Token 配置 API 认证提供方,然后将该 Token 作为 MASTRA_WORKER_AUTH_TOKEN 暴露给编排 worker。基础 Kubernetes 资源请参阅将 Mastra 部署到 Kubernetes。

应用清单,然后验证 Pod 和 API:

kubectl apply -f k8s/
kubectl get pods
kubectl port-forward svc/api 4111:4111

在另一个终端中请求 API 路由:

curl http://localhost:4111/api/agents

步骤执行 URL
步骤执行 URL的直接链接

在完全拆分部署中,编排 worker 通过 HTTP 将工作流步骤执行委托给 API。将 MASTRA_STEP_EXECUTION_URL 设置为 API 的内部 URL,包括 /api 前缀:

MASTRA_STEP_EXECUTION_URL=http://api:4111/api

如果没有此变量,编排 worker 会尝试在自己的进程中执行步骤,而该进程在拆分部署中无法访问完整的 Mastra 运行时。

该端点使用服务器的正常认证管道。如果 API 配置了认证提供方,请将 MASTRA_WORKER_AUTH_TOKEN 设置为该提供方接受的 Bearer Token。Mastra 会将该值作为 Authorization: Bearer 凭据转发。配置的认证提供方会校验该 Token。服务器配置和其他凭据格式请参阅 Worker 认证。

扩展 workers
扩展 workers的直接链接

编排和后台任务 workers 可以水平扩展。PubSub 消费者组会在其实例之间分配事件:

docker compose up -d --scale orchestration-worker=3
docker compose up -d --scale background-task-worker=2

对于 Kubernetes,手动更改 Deployment 的副本数,或使用 HorizontalPodAutoscaler:

kubectl scale deployment/orchestration-worker --replicas=3
kubectl scale deployment/background-task-worker --replicas=2

只运行一个调度 worker。多个调度器轮询同一存储可能会为同一调度发布重复事件。

健康检查
健康检查的直接链接

Worker 构建产物在 PORT(未设置 PORT 时为 4111)上暴露 GET /health。在 startWorkers() 初始化期间,该端点返回 503;每个选定的 worker 成功启动后返回 200。请将此端点用于部署就绪检查。如果你还将其用于存活检查,请配置启动探针或初始延迟,以便 worker 初始化能够完成。

崩溃恢复
崩溃恢复的直接链接

分布式 PubSub 后端会持久化未确认的事件,使编排和后台任务 workers 在重启后能够恢复。当 API 不可用时,失败的步骤执行请求会导致事件再次被投递。由于事件可能被处理多次,处理器应尽可能保持幂等。

调度器在重启后根据当前时间计算下一次触发时间。它不会重放不可用期间已经错过的调度。

如果 API 在步骤执行期间崩溃,该工作可能丢失,工作流运行可能保持 running 状态。参见已知限制和持久化 agent 崩溃恢复。

已知限制
已知限制的直接链接

  • 没有死信队列:失败的事件会被 nack 并重试,但对于在所有重试之后仍然失败的事件,没有 DLQ。
  • 调度器是单实例:运行多个调度器进程会导致重复的调度触发。
  • API 崩溃后运行卡在 "running":工作流步骤执行期间崩溃会使运行处于 running 状态,且不会自动重试。对于持久化 agents,配置 recovery.durableAgents: 'auto',以便服务器重启时自动重新驱动孤立运行。详情请参阅崩溃恢复。

相关内容
相关内容的直接链接