Node-RED 是把消息流画出来的工具:左边拖节点、中间连线、点部署,流程立刻变成在跑的服务。
一个 /ping 接口从画布上拖三个节点就能出来,测下来平均 1.15 毫秒、20 并发 1752 QPS。
这篇按 5.0.9 的完整流程走了一遍:装、首次启动、部署、改端口、安全模式、升级、卸载,每一步都记了耗时和产出的文件。
这是什么
一句话定位
它不是代码生成器,也不是低代码表单工具。它做的事只有一件:把「触发 / 处理 / 输出」串成一条链,让链自己跑。
画布上有三类东西:输入节点(定时 / HTTP 请求 / MQTT 消息)、处理节点(函数 / 判断 / 格式转换)、输出节点(HTTP 响应 / 数据库 / 调试面板)。节点之间用线连起来,线的方向就是消息流向。
整个编辑器是一个网页,服务端是 Node.js。所以它天然可以放在服务器上,用浏览器从别的设备访问。
它解决的具体问题
写过一次性脚本的人都遇到过这些事,Node-RED 的价值就在这些具体场景里:
- 定时任务散在 crontab 和几个 py 文件里:改一个时间要 ssh 进去找,谁也不敢动 → 定时节点上直接双击改间隔,改完 0.05 秒生效
- 两个系统之间要搬数据,写脚本就要写鉴权、重试、日志:一个接口变动就得改代码 → HTTP 节点填上地址,失败重试在节点里勾,不用写一行代码
- 调试全靠 print:脚本跑完才知道哪步错了 → 每个节点的输出都能挂到调试面板,实时看消息内容
- 流程躺在别人电脑里:同事要接手只能看代码 → 整张图存成 2378 字节的 JSON,能塞进 git,能发给别人导入
- 小需求不值得开工程:为了一个「每小时抓一次数据」建个项目太重 → 拖三个节点,部署 0.05 秒
核心能力
- 可视化编排:内置节点按网络 / 功能 / 序列 / 解析分类,HTTP、MQTT、WebSocket、TCP、定时、文件都在里面
- 函数节点:需要写逻辑时直接在节点里写 JS,能拿到完整的 Node 运行时
- 流程即文件:一张图一个 JSON,没有数据库,备份就是拷文件
- 热部署:改完点部署,0.05 秒生效,不用重启进程
- 调试面板:任意节点的输出实时打到侧栏,带时间戳
- 子流程与链接节点:把重复逻辑抽成子流程,跨页面复用
- 插件生态:社区节点装了就能用,也能自己发包
- 多标签页:一个项目里按功能分几张画布,互不干扰
装之前先确认几件事
它跑起来是常驻服务,不是双击就关的桌面软件。启动后 87.6 MB 内存一直占着,当记事本用会觉得重。
先确认是不是真要它整夜开着,再决定装不装。
逻辑藏在画布坐标里。2378 字节的 JSON 大部分是节点位置和 id,真正的判断只有几十个字符。
多人改同一张图会互相踩。要 diff、要 review 的团队不适合它。
默认没有访问控制。启动后同网段的人打开 1880 端口就能改流程、看数据,放到服务器上之前必须配 adminAuth,后面单独写。
环境要求与授权
硬门槛是 Node 22.9
5.0.9 的 package.json 里写死 engines.node: >=22.9。低于这个版本不是「可能有问题」,是装的时候就报警、跑起来直接报语法错误。
$ node -v
v22.22.2 # 本次实测用的版本,满足要求
$ node -e "console.log(require('node-red/package.json').engines)"
{ node: '>=22.9' }
机器上还是 Node 18 的,装之前先升级。用 nvm 的话 nvm install 22 && nvm use 22,系统装的直接去官网下 LTS。
体积与依赖
| 项目 | 数值 |
|---|---|
| 依赖包数(本地安装) | 241 个 |
| 依赖包数(全局安装) | 276 个 |
| node_modules 体积 | 90.9 MB |
| 常驻内存 | 87.6 MB |
| 首次生成的 settings.js | 26847 字节 |
90.9 MB 在 Node 项目里算中等偏大,原因是它打包了整个编辑器前端。装之前按目录体积留一倍余量,日志和备份还要占地方。
授权与费用
Apache 2.0,商用、修改、内部分发都可以,保留声明即可。软件本身不收费,跑在自己的机器上也没有任何账号或订阅。
要花钱的只有服务器。实测常驻 87.6 MB,按这个量级选配置即可。流程里要调外部 API 的话,那部分费用是对方的,跟 Node-RED 无关。
安装:两条路线,都实测过
先选路线
官方给了不止一种装法,这里只写实测跑通的两条。Docker 与源码构建在当前环境不具备条件,未验证的步骤不写。
| 路线 | 适合谁 | 实测耗时 | 装完怎么启动 |
|---|---|---|---|
| 本地安装 | 想固定版本、随时能删干净 | 39 秒 | node node_modules/node-red/red.js |
| 全局安装 | 想在任何目录敲一句就起来 | 36 秒 | node-red |
两条路线装的东西一样,区别只在落点和启动命令。选本地安装的好处是整个目录能打包带走,换机器拷过去就能跑。
方式一 · 本地安装(推荐)
建个空目录,把 Node-RED 当普通依赖装进去:
mkdir node-red && cd node-red
npm install node-red --prefix . --registry=https://registry.npmmirror.com
# 39 秒后
added 241 packages in 39s
--prefix . 这一句别省。不加的话 npm 有可能认为目标目录「已经是最新」而什么都不做,装完 node_modules 是空的。
同一个目录第二次执行时最容易骗人:输出写着 up to date in 12s,看着像成功,实际一个文件都没装。
装完启动:
node node_modules/node-red/red.js --port 1880 --userDir ./data
--userDir 指定数据目录,不指定就默认在 ~/.node-red。指定成项目内目录的好处是备份和迁移都只要拷一个文件夹。
方式二 · 全局安装
想在任何目录直接敲 node-red 就用这条:
npm install -g node-red --prefix D:\node-red-global
# 36 秒后
added 276 packages in 36s
装完 --prefix 目录下会多出四个入口文件:node-red、node-red.cmd、node-red-pi、node-red-pi.cmd。Windows 上用 .cmd 那个。把这四个文件所在目录加进 PATH 之后,启动就变成一句 node-red --port 1880。
首次启动会生成什么
用一个全新的空目录启动,11.04 秒之后目录里多出这些东西。第一次启动比后续慢,因为在初始化:
| 文件 | 字节 | 作用 |
|---|---|---|
| settings.js | 26847 | 全部配置,端口、认证、存储路径都在这 |
| .config.nodes.json | 15384 | 已安装节点的清单 |
| .config.runtime.json | 133 | 运行时状态 |
| .config.runtime.json.backup | 40 | 上一次运行状态的备份 |
| package.json | 120 | 给额外安装的节点用 |
| lib/ | 目录 | 静态资源和库 |
| node_modules/ | 目录 | 额外装的节点包 |
注意这里没有 flows.json。它在第一次点部署之后才生成,实测 8 个节点的流程存下来是 2378 字节。目录里没有这个文件,说明还没部署过任何流程。
第一次打开该做什么
界面分四块
浏览器打开 http://127.0.0.1:1880 之后,先把这四块认清楚,后面就不会乱:
- 左侧节点面板:按功能分组,inject 在「通用」,function 在「功能」,http in 和 response 在「网络」
- 中间画布:节点拖进来摆位置,从一个节点右侧的小圆点拖到另一个节点左侧就连上了
- 右上部署按钮:改完必须点它,不改不生效
- 右侧调试面板:点右上那个虫子图标打开,所有挂到 debug 节点的消息都往这里打

刚打开时会连弹两个窗,一个是版本更新通知,一个是新功能导览,都盖在画布正中。点掉继续,不影响使用。
部署第一个流程
四个节点做一条最小链路,定时触发、处理、输出各一个。
1. 左侧「通用」拖 inject 到画布
2. 双击它,把 repeat 设成 2(每 2 秒触发一次),点完成
3. 「功能」拖 function,双击写:msg.payload = new Date().toISOString(); return msg;
4. 「通用」拖 debug,双击确认输出选 msg.payload
5. 从 inject 右侧圆点拖线到 function,再拖一条到 debug
6. 点右上「部署」,选「完整」
部署耗时 0.05 秒。之后右侧调试面板每 2 秒自己多一条时间戳,说明调度在跑。

怎么确认它在跑
两条最快的验证路径,一条看面板是否活着,一条看流程里的接口通不通:
# 1. 面板是否活着
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:1880/
200
# 2. 流程里的接口
curl -s http://127.0.0.1:1880/ping
{"ok":true,"t":1792849084000}
第二条只在流程里配了 http in 节点时才有。返回 404 说明流程没部署成功,或者那个节点没连到 http response。
日常维护
下面这些动作都很短,先把这一节涉及的数字集中放一张表,后面照着改就行。
| 动作 | 数值 | 说明 |
|---|---|---|
| 改端口后启动 | 2.51 秒 | 换成 1885 实测 |
| 安全模式启动 | 2.51 秒 | 1886 端口,接口全 404 |
| settings.js | 26847 字节 | 端口与认证都在这 |
| flows.json | 2378 字节 | 8 个节点的流程 |
| flows_cred.json | 0 字节 | 没配凭据时 |
| 同版本重装 | 13.4 秒 | npm 同一条命令 |
改端口
启动参数和环境变量两种方式,实测都生效,从启动到可访问 2.51 秒:
# 参数方式
node node_modules/node-red/red.js --port 1885
# 环境变量方式(容器里常用)
set PORT=1885
node node_modules/node-red/red.js
要永久改就动 settings.js 里的 uiPort,写死一个数字,或者读环境变量都可以。
安全模式
流程改崩了、启动就卡住的时候用。它会起来但不加载已经部署的流程,让你进编辑器改:
node node_modules/node-red/red.js --safe --port 1886
# 实测:2.51 秒可访问,但流程里的接口一律 404
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:1886/ping
404
这个 404 就是安全模式在工作。看到能进编辑器、但接口全 404,不用怀疑装坏了。
加访问控制
默认谁都能改流程。放到服务器上之前,把 settings.js 里 adminAuth 那段取消注释,密码用官方工具生成哈希,不要手写:
npx node-red-admin hash-pw
# 输入两次密码,输出 $2b$08$... 粘贴到 settings.js 的 password 字段
配好之后打开面板会先要账号密码,接口不受影响(接口认证是另一套 httpNodeAuth)。
备份
没有数据库,备份就是拷两个文件:flows.json(2378 字节)加 flows_cred.json(存凭据,没配就是 0 字节)。
cp data/flows.json data/flows_cred.json backup/2026-10-25/
settings.js 建议一起备,26847 字节。改过的认证配置和端口都在里面,重装之后不拷回去会丢。
升级
同一条 npm 命令,版本已经是新的就直接过:
npm install node-red --prefix . --registry=https://registry.npmmirror.com
# 实测:13.4 秒,up to date in 12s
13.4 秒是同版本重装的耗时,跨版本要下载新包会更久。升级前把 flows.json 备一份,大版本之间偶有节点参数改名。
卸载
本地安装的,删目录就完了,没有注册表、没有服务、没有残留:
rm -rf node-red # Linux / macOS
rd /s /q node-red # Windows
npm uninstall -g node-red --prefix D:\node-red-global # 全局装的补这一句
性能实测
端点延迟与并发
画布上那条 /ping 链路只有三个节点,function 里三行代码。串行打 50 次,再压 20 并发 200 次:
| 测试方式 | 结果 |
|---|---|
| 串行 50 次平均 | 1.15 毫秒 |
| 串行中位数 | 0.92 毫秒 |
| 最快 / 最慢 | 0.73 / 4.92 毫秒 |
| 20 并发 200 次 | 1752.4 QPS |
| 200 个请求跑完 | 0.11 秒 |
| 部署 8 个节点 | 0.05 秒 |
1752 QPS 是 200 个请求 0.11 秒跑完算出来的。这个量级说明画图不等于慢,开销主要在 HTTP 那一层,节点链本身是内存里传对象。
启动与资源
| 场景 | 耗时 |
|---|---|
| 全新目录首次启动 | 11.04 秒 |
| 已有 flows 启动 | 3.05 秒 |
| 改端口后启动 | 2.51 秒 |
| 安全模式启动 | 2.51 秒 |
| 同版本重装 | 13.4 秒 |
| 常驻内存 | 87.6 MB |
11.04 秒和 3.05 秒的差别在初始化:第一次要生成 settings.js(26847 字节)和节点清单(15384 字节),之后直接读现成的。
几个真踩过的报错
下面五条都是实际撞上的,按症状能直接对上。
| 症状 | 原因 | 处理 |
|---|---|---|
| 409 version_mismatch | POST /flows 没带 rev | 先 GET 取 rev 再放回 body |
| 部署后画布空白 | 节点没挂 tab | 加 type=tab 并给每个节点填 z |
| 接口 404 | 安全模式或没连 response | 去掉 --safe,补 http response |
| 端口占用 | 1880 被别的进程占了 | 换端口或用 netstat 找占用者 |
| up to date 但缺模块 | 没加 --prefix | 补 --prefix 绝对路径重装 |
用脚本部署报 409 version_mismatch
界面点部署不会有这个问题,走接口才会。Node-RED 5 要求带版本号,得先 GET 拿 rev 再原样放回 POST:
GET /flows -> {"rev":"a1b2c3d4e5f6","flows":[...]}
POST /flows -> {"rev":"a1b2c3d4e5f6","flows":[...]}
Header: Node-RED-API-Version: v2
部署成功了但画布是空的
节点没挂在标签页上。数组第一条必须是 type=tab 的节点,其余每个节点都要带 "z":"<tab 的 id>"。少了这个字段,接口不报错、流程也不出现,表现是画布空白、接口全 404。
接口 404 但流程看着没问题
先看是不是安全模式起来的(--safe 会故意不加载流程),再看 http in 节点有没有连到 http response。这两条都不是的话,检查 http in 里的 URL 有没有带错前缀。
端口被占用
换成 1885 之类的端口再起,或者先找出占用者:
netstat -ano | findstr ":1880" # Windows
lsof -i :1880 # Linux / macOS
npm 说 up to date 但启动报找不到模块
没加 --prefix,npm 把目标目录判断成「已满足」直接跳过。补上 --prefix <绝对路径> 重装一次就好。
编辑器打开一片空白
先等一下,界面要加载几 MB 的脚本。等了还是白的按 F12 看控制台:常见原因是被浏览器插件拦了请求,或者反向代理把 /red 路径吃掉了。
什么场景值得上
手上有一堆「每隔几小时跑一次」「A 的数据进 B」这类小事,又不值得为每件事建工程的人,用它最顺。拖三个节点、部署 0.05 秒,比写脚本快。
要把流程放到服务器上、让同事也能看和改,它也合适:一个 87.6 MB 的常驻进程,浏览器打开就能改。
反过来,需要版本管理、单元测试、多人并行开发的逻辑,别用它。2378 字节的 JSON 存的是坐标和连线,diff 出来没法看,这活该交给代码。
手上只有一个定时任务、且永远不改的,也不用上这套。crontab 一行就够了,多一个 87.6 MB 的进程不划算。







