队列模式#
你可以根据需求以不同的模式运行 n8n。队列模式(queue mode)提供了最佳的可扩展性。
二进制数据存储
n8n 在使用文件系统作为二进制数据存储时,不支持队列模式。如果你的工作流在队列模式下需要持久化二进制数据,可以使用 S3 外部存储。
工作原理#
在队列模式下运行时,你会设置多个 n8n 实例:一个主实例(main instance)负责接收工作流信息(例如触发器),以及多个工作实例(worker instances)负责执行任务。
每个工作实例都是独立的 Node.js 进程,运行在 main 模式下,但由于具有较高的 IOPS(每秒输入输出操作数),能够处理多个并发的工作流执行。
通过使用工作实例并以队列模式运行,你可以根据负载需要灵活地扩展(增加 worker)或缩减(减少 worker)n8n 的处理能力。
具体流程如下:
- 主 n8n 实例处理定时任务和 Webhook 调用,生成工作流执行任务(但不直接运行)。
- 它将执行 ID 发送给消息代理 Redis,由 Redis 维护待处理执行任务的队列,并允许下一个可用的工作实例从中获取任务。
- 工作池中的某个 worker 从 Redis 获取消息。
- worker 使用执行 ID 从数据库中获取完整的工作流信息。
- 完成工作流执行后,worker 会:
- 将执行结果写入数据库。
- 向 Redis 发送通知,表明该执行已结束。
- Redis 通知主实例执行已完成。
"示意图:显示主 n8n 实例、Redis、n8n 工作节点(workers)和 n8n 数据库之间的数据流"
配置工作节点(workers)#
工作节点是实际执行任务的 n8n 实例。它们从主 n8n 进程接收需要执行的工作流信息,执行这些工作流,并在每次执行完成后更新状态。
设置加密密钥(encryption key)#
n8n 在首次启动时会自动生成一个加密密钥。你也可以根据需要通过环境变量提供自定义密钥。
主 n8n 实例的加密密钥必须与所有工作节点和 webhook 处理节点共享,以确保这些工作节点能够访问数据库中存储的凭证(credentials)。
为每个工作节点在配置文件中设置加密密钥,或通过设置相应的环境变量:
1| ``` export N8N_ENCRYPTION_KEY=<main_instance_encryption_key>
---|---
### 设置执行模式(executions mode)#
**数据库注意事项**
n8n 推荐使用 Postgres 13 或更高版本。不建议在 SQLite 数据库上将执行模式设置为 `queue` 来运行 n8n。
在主实例和所有工作节点上,通过以下命令将环境变量 `EXECUTIONS_MODE` 设置为 `queue`:1
| ```
export EXECUTIONS_MODE=queue---|---
或者,你可以在配置文件中将 executions.mode 设置为 queue。
启动 Redis
在独立机器上运行 Redis 你可以将 Redis 运行在单独的机器上,只需确保 n8n 实例可以访问它即可。
要在 Docker 容器中运行 Redis,请按照以下说明操作: 运行以下命令来启动一个 Redis 实例:
1| ``` docker run --name some-redis -p 6379:6379 -d redis
---|---
默认情况下,Redis 在 localhost 的 6379 端口上运行,且无需密码。根据你的 Redis 配置,请为 n8n 主进程设置以下配置项,以便 n8n 能够与 Redis 交互。
| 使用配置文件 | 使用环境变量 | 说明 |
|---|---|---|
queue.bull.redis.host:localhost | QUEUE_BULL_REDIS_HOST=localhost | 默认情况下,Redis 运行在 localhost 上。 |
queue.bull.redis.port:6379 | QUEUE_BULL_REDIS_PORT=6379 | 默认端口为 6379。如果 Redis 运行在其他端口,请修改该值。 |
你还可以设置以下可选配置:
| 使用配置文件 | 使用环境变量 | 说明 |
|---|---|---|
queue.bull.redis.username:USERNAME | QUEUE_BULL_REDIS_USERNAME | 默认情况下 Redis 不需要用户名。若使用特定用户,请配置此变量。 |
queue.bull.redis.password:PASSWORD | QUEUE_BULL_REDIS_PASSWORD | 默认情况下 Redis 不需要密码。若启用了密码认证,请配置此变量。 |
queue.bull.redis.db:0 | QUEUE_BULL_REDIS_DB | 默认值为 0。若更改了该值,请同步更新配置。 |
queue.bull.redis.timeoutThreshold:10000ms | QUEUE_BULL_REDIS_TIMEOUT_THRESHOLD | 指定当 Redis 不可用时,n8n 在退出前应等待的时间。默认值为 10000(毫秒)。 |
queue.bull.gracefulShutdownTimeout:30 | N8N_GRACEFUL_SHUTDOWN_TIMEOUT | 工作进程(worker)在终止前完成当前任务的优雅关闭超时时间。默认值为 30 秒。 |
现在你可以启动 n8n 实例,它将连接到你的 Redis 实例。
启动工作进程#
你需要启动工作进程(worker processes),以允许 n8n 执行工作流。如果你想在独立的机器上部署工作进程,请在该机器上安装 n8n,并确保其能够连接到你的 Redis 实例和 n8n 数据库。
从项目根目录执行以下命令来启动工作进程:
1| ``` ./packages/cli/bin/n8n worker
---|---
如果你使用 Docker,请运行以下命令:1
| ```
docker run --name n8n-queue -p 5679:5678 docker.n8n.io/n8nio/n8n worker
---|---
你可以设置多个工作进程(worker processes)。请确保所有工作进程都能访问 Redis 和 n8n 数据库。
#### 工作节点服务器#
每个工作进程都会运行一个服务器,该服务器暴露了若干可选的端点:
* `/healthz`:如果你启用了 `QUEUE_HEALTH_CHECK_ACTIVE` 环境变量,则返回工作节点是否正常运行
* `/healthz/readiness`:如果你启用了 `QUEUE_HEALTH_CHECK_ACTIVE` 环境变量,则返回工作节点的数据库(DB)和 Redis 连接是否就绪
* 凭据覆盖端点(credentials overwrite endpoint)
* `/metrics`
#### 查看正在运行的工作节点#
功能可用性
* 在自托管企业版(Self-hosted Enterprise plans)中可用。
* 如果你希望在云企业版(Cloud Enterprise)中使用此功能,请联系 n8n。你可以通过选择 设置 > 工作节点(Workers) 在 n8n 中查看正在运行的工作节点及其性能指标。
使用队列运行 n8n#
当使用队列模式运行 n8n 时,所有生产环境工作流的执行都会由工作进程(worker processes)处理。这意味着即使是 webhook 调用也会被委派给工作进程处理,这可能会带来一定的开销和额外的延迟。
Redis 作为消息代理(message broker),数据库用于持久化数据,因此必须能够访问两者。此架构下不支持使用 SQLite 运行分布式系统。
数据迁移
如果你想将数据从一个数据库迁移到另一个数据库,可以使用导出(Export)和导入(Import)命令。请参考 n8n 的 CLI 命令文档 了解如何使用这些命令。
Webhook 处理器#
请注意:
Webhook 处理进程依赖 Redis,并且也需要设置 EXECUTIONS_MODE 环境变量。请参考上方的 配置工作节点(configure the workers) 部分来设置 webhook 处理节点。
Webhook 处理器是 n8n 中另一层扩展机制。配置 webhook 处理器是可选的,但它允许你对传入的 webhook 请求进行横向扩展。
该方法使 n8n 能够处理大量并行请求。你只需相应地增加更多的 webhook 进程和工作节点即可。webhook 进程将在相同的端口上监听请求(默认:5678)。建议在容器或独立机器中运行这些进程,并使用负载均衡系统来合理分发请求。
n8n 不建议将主进程加入负载均衡池中。如果你将主进程加入负载均衡池,它将接收请求并可能承受较大负载,从而导致编辑、查看和操作 n8n 用户界面(UI)时性能下降。
你可以通过在根目录执行以下命令来启动 webhook 处理器:
1| ``` ./packages/cli/bin/n8n webhook
---|---
如果你使用 Docker,请使用以下命令:1
| ```
docker run --name n8n-queue -p 5679:5678 -e "EXECUTIONS_MODE=queue" docker.n8n.io/n8nio/n8n webhook---|---
配置 Webhook URL#
要配置你的 webhook URL,请在运行主 n8n 实例的机器上执行以下命令:
1| ``` export WEBHOOK_URL=https://your-webhook-url.com
---|--- 你也可以在配置文件中设置此值。
配置负载均衡器#
当使用多个 webhook 进程时,你需要一个负载均衡器来路由请求。如果你为 n8n 实例和 webhook 使用相同的域名,可以按如下方式配置负载均衡器:
- 将所有匹配
/webhook/*的请求重定向到 webhook 服务器池 - 其他所有路径(n8n 内部 API、编辑器的静态文件等)应路由到主进程
注意: 手动工作流执行的默认 URL 是 /webhook-test/*。请确保这些 URL 被路由到你的主进程。
你可以通过配置文件中的 endpoints.webhook 或使用环境变量 N8N_ENDPOINT_WEBHOOK 来更改此路径。如果进行了更改,请相应地更新你的负载均衡器。
在主进程中禁用 webhook 处理(可选)#
你已有专门的 webhook 处理器用于执行工作流,因此可以在主进程中禁用 webhook 处理功能。这将确保所有 webhook 的执行都在 webhook 处理器中进行。在配置文件中将 endpoints.disableProductionWebhooksOnMainProcess 设置为 true,以使 n8n 不在主进程中处理 webhook 请求。
或者,你可以使用以下命令:
1| ``` export N8N_DISABLE_PRODUCTION_MAIN_PROCESS=true
---|---
在主进程中禁用 webhook 处理后,请运行主进程,但不要将其加入负载均衡器的 webhook 服务器池。
## 配置工作进程并发数#
你可以通过 `concurrency` 参数定义每个工作进程可并行运行的任务数量,默认值为 `10`。要修改该值,请使用:1
| ```
n8n=5---|---
并发与扩展建议#
n8n 建议将工作节点的并发数设置为 5 或更高。若工作节点数量较多但并发值过低,可能会耗尽数据库连接池,导致处理延迟或失败。
多主节点配置(Multi-main setup)#
功能可用性
- 仅限自托管企业版(Self-hosted Enterprise plans)可用。
在队列模式下,你可以运行多个 `main` 进程以实现高可用性。
在单实例模式下,`main` 进程执行两组任务:
* **常规任务(regular tasks)**,例如运行 API、提供 UI 服务以及监听 webhook;
* **至多一次任务(at-most-once tasks)**,例如执行非 HTTP 触发器(定时器、轮询器以及 RabbitMQ 和 IMAP 等持久连接),以及清理执行记录和二进制数据。
在多主节点(multi-main)架构中,存在两种类型的 `main` 进程:
* **从节点(followers)**:仅运行 **常规任务**;
* **主节点(leader)**:同时运行 **常规任务和至多一次任务**。
### 主节点指定#
在多主节点设置中,所有 `main` 实例会透明地处理领导权选举过程。如果当前主节点变得不可用(例如崩溃或事件循环过载),其他从节点可以接管成为新的主节点。若原主节点恢复响应,则自动降级为从节点。
### 配置多主节点设置#
要部署 n8n 的多主节点架构,请确保满足以下条件:
* 所有 `main` 进程均运行在队列模式下,并连接到 Postgres 和 Redis。
* 所有 `main` 和 `worker` 进程运行相同版本的 n8n。
* 所有 `main` 进程已将环境变量 `N8N_MULTI_MAIN_SETUP_ENABLED` 设置为 `true`。
* 所有 `main` 进程位于启用了会话持久化(粘性会话,sticky sessions)的负载均衡器之后。
如有需要,可调整主节点键(leader key)相关配置:
使用配置文件 | 使用环境变量 | 说明
---|---|---
`multiMainSetup.ttl:10` | `N8N_MULTI_MAIN_SETUP_KEY_TTL=10` | 多主节点架构中主节点键的生存时间(TTL),单位为秒。
`multiMainSetup.interval:3` | `N8N_MULTI_MAIN_SETUP_CHECK_INTERVAL=3` | 多主节点架构中检查主节点状态的时间间隔,单位为秒。