n8n 工作流执行是 n8n 自动化的心脏。无论你是在开发阶段调试工作流,还是让它在生产环境中自动运行,理解执行的方式至关重要。本教程将带你从零开始,深入掌握 n8n 的各种执行模式、调试技巧,以及如何管理和优化工作流执行。
执行就是工作流的一次运行。每次工作流从开始到结束的完整流程,n8n 都会记录下来。你可以查看每次执行的详细信息,包括数据流、错误信息、执行时长等。
n8n 提供了两种执行模式:
在工作流中选择 Executions 选项卡,你可以看到该工作流的所有执行记录。
在 n8n 首页点击 Executions 选项卡,你可以看到整个 n8n 实例所有工作流的执行记录。这对于监控所有自动化任务非常有用。
核心特性:让你在开发过程中快速迭代测试
优点:
✅ 完整的工作流运行
✅ 实时查看数据流
✅ 支持修改输入数据进行测试
✅ 支持数据钉住功能使用场景示例:
核心特性:只运行工作流的一部分,而不是整个流程
如何使用:
为什么要用部分执行?
常见错误及解决方案:
核心特性:在真实场景中自动运行
配置步骤:
重要提示:
脏节点是指那些曾经成功执行过,但现在输出数据被认为"过期"或"不可靠"的节点。在画布上,脏节点会显示一个黄色三角形而不是绿色勾号。
以下操作会导致节点被标记为脏:
方法很简单——重新执行该节点!
你可以:
数据钉住让你可以"冻结"某个节点的输出数据。在后续执行中,n8n 会跳过该节点的执行,直接使用钉住的数据继续流程。
场景1:你在测试一个从 API 获取的大量数据
✅ 第一次执行 API 调用获取数据
✅ 钉住这个数据
✅ 后续执行直接用钉住的数据,不再调用 API
✅ 快速测试后续节点的逻辑,节省时间和 API 配额
场景2:测试复杂的条件分支
✅ 钉住某个中间节点的数据
✅ 快速测试不同的分支逻辑
✅ 无需每次都重新执行前面的所有节点当工作流处于 Active(生产环境)时,所有钉住的数据都会被忽略。只有在手动执行和开发时,钉住的数据才会起作用。
n8n 提供了强大的调试功能,让你可以在编辑器中重新运行过去的失败执行。
有时你想用之前成功的执行数据来验证新的逻辑:
有两种重试方式:
方式1:用当前保存的工作流重试
方式2:用原始工作流重试
你可以在工作流运行时添加自定义元数据,n8n 会将其记录下来。这些数据可以用于:
使用 Code 节点:
// 添加单条自定义数据
$input.first().item.json.customData = {
'project': 'marketing_campaign',
'priority': 'high'
};
// 或者使用专门的方法
$input.first().item.json.$executionData = {
'project': 'marketing_campaign',
'priority': 'high'
};在工作流中使用 Code 节点访问:
// 获取整个自定义数据对象
const customData = $input.first().item.json.$executionData;
// 获取特定值
const project = customData.project;在筛选功能中:
priority 为 high 的执行调试功能特别有用于:
💡 技巧1:使用 Sticky Note 节点添加注释
✅ 在工作流中记录关键逻辑
✅ 其他人(或未来的自己)可以快速理解
💡 技巧2:分段钉住数据
✅ 在关键节点后钉住数据
✅ 快速定位问题所在
💡 技巧3:使用 Limit 节点
✅ 在测试时限制数据量
✅ 快速执行,节省时间我们将创建一个**"天气数据收集器"**工作流,演示以下概念:
这个工作流会:
将以下代码复制到你的 n8n 中(菜单 → Import from Clipboard):
{
"name": "Weather Data Collection Workflow",
"nodes": [
{
"parameters": {
"trigger": "every",
"unit": "minutes",
"value": 30
},
"id": "1",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"method": "GET",
"url": "https://api.open-meteo.com/v1/forecast?latitude=31.2304&longitude=120.5954¤t=temperature_2m,relative_humidity_2m,weather_code",
"responseFormat": "json"
},
"id": "2",
"name": "Get Weather Data",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [450, 300],
"credentials": {}
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "return [\n {\n ...item.json,\n temperature: item.json.current.temperature_2m,\n humidity: item.json.current.relative_humidity_2m,\n city: 'Suzhou',\n priority: item.json.current.temperature_2m > 30 ? 'high' : 'normal'\n }\n]"
},
"id": "3",
"name": "Process Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [650, 300]
},
{
"parameters": {
"conditions": {
"nodeVersion": 2.1,
"conditions": [
{
"value1": "={{ $json.temperature }}",
"value2": 30,
"operator": "gt"
}
]
}
},
"id": "4",
"name": "Temperature Check",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [850, 200]
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// 设置自定义执行数据\n$input.first().item.json.$executionData = {\n 'city': 'Suzhou',\n 'alert_type': 'high_temp'\n};\nreturn $input.getAll()"
},
"id": "5",
"name": "Set Custom Data - High Temp",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1050, 100]
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// 设置自定义执行数据\n$input.first().item.json.$executionData = {\n 'city': 'Suzhou',\n 'alert_type': 'normal_temp'\n};\nreturn $input.getAll()"
},
"id": "6",
"name": "Set Custom Data - Normal",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1050, 300]
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Get Weather Data",
"type": "main",
"index": 0
}
]
]
},
"Get Weather Data": {
"main": [
[
{
"node": "Process Data",
"type": "main",
"index": 0
}
]
]
},
"Process Data": {
"main": [
[
{
"node": "Temperature Check",
"type": "main",
"index": 0
}
]
]
},
"Temperature Check": {
"main": [
[
{
"node": "Set Custom Data - High Temp",
"type": "main",
"index": 0
}
],
[
{
"node": "Set Custom Data - Normal",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"id": "12",
"meta": {
"instanceId": "7d69e7b7a28c89e2d4e5f8c9a1b2c3d4"
}
}| 节点 | 作用 | 执行模式 |
|---|---|---|
| Schedule Trigger | 每 30 分钟触发一次 | 触发器 |
| Get Weather Data | 调用开放天气 API | HTTP 请求 |
| Process Data | 提取并转换数据 | Code 节点 |
| Temperature Check | 根据温度分支处理 | IF 条件 |
| Set Custom Data | 添加自定义标签 | Code 节点 |
| 功能 | 使用场景 | 快捷键/方式 |
|---|---|---|
| 手动执行 | 开发测试 | 点击"Execute Workflow"按钮 |
| 部分执行 | 快速测试单个节点 | 选择节点 → 点击"Execute step" |
| 数据钉住 | 冻结节点输出 | 点击"Pin data"按钮 |
| 调试执行 | 排查生产故障 | Executions → 点击"Debug in editor" |
| 重试执行 | 重新运行失败任务 | Executions → 点击"Retry execution" |
| 自定义数据 | 标记和筛选执行 | 在 Code 节点中设置 $executionData |
| 脏节点清理 | 清除过期数据标记 | 执行该节点或整个工作流 |
A:不会。n8n 会分别记录所有执行,但在 Executions 列表中都能看到。你可以通过时间戳和其他信息区分。
A:为了确保生产稳定性。生产环境必须始终从真实的触发条件开始执行,而不是依赖你在开发时钉住的测试数据。
A:使用 Filters 功能:
A:可以的,使用特殊变量 $execution.id。例如在 Code 节点中:
const executionId = $execution.id;A:不会。脏节点标记是针对开发环境的。生产执行按照当前保存的工作流配置完整运行,不受脏节点标记影响。
[1] 官方文档: https://docs.n8n.io/workflows/executions/
[2] n8n 系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#