首页 / 资讯中心 / 文章详情

Node.js后台进程更新后如何正确重启:nohup、pm2与forever实操指南

Node.js后台进程更新后如何正确重启:nohup、pm2与forever实操指南 ★ FEATURED ARTICLE
1. 项目背景搞清楚“更新文件”和“后台运行”之间的那点事先说个最容易被新手忽略的坑很多人以为把wework-verify.js文件改完保存后台的服务就“自动生效”了。实测下来根本不是这么回事。Node.js 进程启动之后代码是加载到内存里跑的你改的是磁盘上的文件跟已经跑起来的进程完全是两码事。除非你用了nodemon这类带自动重启的监听工具否则改完文件必须手动重启进程新代码才会真正生效。这篇文章解决的就是这个场景一台服务器或者你自己的电脑上wework-verify.js正以某种方式在后台运行你更新了文件内容现在需要一条命令让它重新加载新代码继续跑。我的建议是先把“后台运行”的本质弄清楚。日常操作里所谓“后台运行”无非是三种情况用nohup启动的普通进程靠 PID 管理。用pm2这个 Node.js 进程守护工具管理的服务。用forever或者其他类似工具托管的进程。这三种方式的更新命令完全不一样用错了轻则重启失败重则直接杀掉进程还得重新找启动参数。后面我会挨个说清楚你只要对照自己当初是怎么启动的抄对应的命令就行。2. 先判断你属于哪种运行方式2.1 用 nohup 启动的裸进程如果你当初的启动命令长这样nohup node wework-verify.js app.log 21 那说明你的服务是一个“无人看管”的裸进程。这种方式的好处是简单缺点是进程一旦崩了不会自动拉起更新后也要手动处理。判断方法很简单ps -ef | grep wework-verify如果能看到一个node wework-verify.js的进程而且它的父进程 PID 是 1或者是一个很靠前的数字多半就是 nohup 拉起来的。2.2 用 pm2 管理的托管进程pm2 是目前 Node.js 项目里最主流的进程守护工具。如果你当初用类似下面的命令启动pm2 start wework-verify.js --name wework-verify或者pm2 start wework-verify.js -i 1 --name wework-verify那你的服务就在 pm2 的管辖范围内。pm2 的价值不只是“后台运行”它还自带崩溃自动重启、日志管理、开机自启这些功能所以对长期跑的服务来说pm2 是远比 nohup 靠谱的选择。2.3 用 forever 管理的进程forever 也是老牌的 Node.js 守护工具虽然现在用的人少了但不少老项目里还在用。启动命令一般长这样forever start wework-verify.js判断方式是执行forever list如果列表里有wework-verify.js那就是 forever 管的。3. 各方式对应的更新命令直接照抄3.1 如果你是 nohup 方式核心步骤是两步杀掉旧进程 → 重新拉起新进程。先找到 PIDps -ef | grep wework-verify | grep -v grep输出会类似这样root 12345 1 0 10:30 ? 00:00:10 node wework-verify.js第二列的数字12345就是 PID。杀掉它kill 12345这里有个小技巧如果直接kill杀不掉进程可能正在处理某些请求或者处于僵死状态再用kill -9 12345强制杀。但不要一上来就kill -9因为强杀可能让你丢失某些未写完的数据尤其是涉及文件读写或者数据库操作的脚本。杀完之后重新启动nohup node wework-verify.js app.log 21 这里再说深一点 app.log 21是把标准输出和标准错误都重定向到app.log这样就算程序里有什么console.log或者报错信息都能在日志文件里看到排查问题的时候会方便很多。如果你不想输出到日志文件只想让它在后台安静地跑也可以写成nohup node wework-verify.js /dev/null 21 但我个人强烈建议保留日志因为后面真出问题的时候没有日志就只能干瞪眼。3.2 如果你是 pm2 方式pm2 就优雅多了一条命令搞定pm2 restart wework-verify注意这里的wework-verify不是文件名是你在pm2 start时指定的应用名--name后面的值。如果你当时没指定名字默认会变成文件名去掉后缀那通常就是wework-verify。不确定的话先看一下pm2 list输出里Name列会显示所有应用的名字。找到之后直接 restart 即可。还有个更省事的写法直接写文件路径pm2 restart wework-verify.jspm2 也支持。它会自动匹配名字或者路径实测下来比按名字匹配更不容易出错。如果只是想重新加载代码而不中断进程针对某些 HTTP 服务场景pm2 还支持pm2 reload wework-verifyreload和restart的区别是reload是平滑重载先起一个新的工作进程等新进程就绪后再把旧进程换掉整个过程对客户端来说几乎无感知restart是直接干掉旧进程再起新的中间会有一个短暂的不可用窗口。如果你的wework-verify.js处理的是内部验证逻辑不是对外的 HTTP 服务用restart就完全够了但如果它对外提供服务reload是更好的选择。3.3 如果你是 forever 方式先看进程列表forever list找到对应的脚本路径和 uid然后forever restart wework-verify.js或者用 uidforever restart uidforever 没有 pm2 那么完善的平滑重载机制但 restart 本身已经足够应对绝大多数场景。4. 核心实操环节整理一套完整的更新流程4.1 更新前先备份这一步很多人会跳过但我建议养成习惯。特别是你改的是wework-verify.js这种带有业务逻辑的脚本万一改出来的代码有语法错误可能连启动都启动不了。备份命令很简单cp wework-verify.js wework-verify.js.bak.$(date %Y%m%d%H%M%S)后面加个时间戳方便回溯是哪一版。4.2 更新代码文件这个环节没有太多可讲的用编辑器改完保存。但有一点关键提醒改完之后一定要检查语法。node --check wework-verify.js--check是 Node.js 自带的语法检查模式只校验语法不执行代码。如果这里报错比如多了个括号、少了个引号、某个变量没定义导致的低级错误趁早修掉。这个命令我每次更新完文件都会跑一遍看着它输出干净才敢去重启服务。4.3 执行重启命令根据你之前判断的运行方式执行对应命令pm2 用户执行pm2 restart wework-verifynohup 用户执行kill PID nohup node wework-verify.js app.log 21 forever 用户执行forever restart wework-verify.js4.4 验证服务恢复正常重启之后千万别急着关终端走人得先确认服务真的起来了。这一步是区分“老手”和“新手”的分水岭。先看进程是否存在ps -ef | grep wework-verify | grep -v grep再看日志里有没有异常输出tail -50 app.log如果用的是 pm2看状态更直观pm2 statusstatus列应该显示online如果显示errored或者stopped说明启动时挂了。最后是实际的业务验证。如果这个脚本是处理某种验证逻辑的最好实际调一次接口或者触发一次流程确认新逻辑生效。这一步一定不能省因为有些代码逻辑错误不会导致进程崩溃但会静默地产生错误结果。5. 常见问题与排查技巧实录5.1 重启之后进程立刻消失这是最高频的问题。大部分原因是代码中有语法错误或者运行时的未捕获异常。先别急着重启去看日志文件tail -100 app.log如果是 pm2 管理直接pm2 logs wework-verify --lines 100日志里会明确写出报错原因。我记得有一次是某个变量名大小写写错了Node.js 直接抛ReferenceError进程起不来。这种情况改回变量名再重启就好了。5.2 端口被占用导致启动失败如果你的wework-verify.js会监听某个端口可能重启时提示EADDRINUSE。这说明上一次的进程没有完全退出或者有别的进程占了端口。解决方案lsof -i :端口号找到对应 PID 杀掉再重启服务。如果不确定端口号看脚本里listen或者服务配置用的哪个端口即可。5.3 更新完后运行结果和预期不一致这种情况最折磨人因为进程明明是好的逻辑也改了但效果没变。大概率是你重启错了进程。比如你之前用 pm2 启动的但更新后用 nohup 又拉了一个两个进程同时在跑请求被旧的进程处理了。排查命令ps -ef | grep wework-verify如果看到两个以上的node wework-verify.js进程说明出现了多实例并存的情况。处理办法是把所有相关进程全部杀掉然后用你常用的一种方式统一拉起来。多进程并存这个问题我在实际项目里踩过好几次根源就是有时候图省事换了一种启动方式结果新旧进程都在跑测试结果时好时坏。5.4 后台进程在终端关闭后自动退出这其实是 nohup 用户最常见的困惑。如果你用了node wework-verify.js 那当你关闭终端的时候进程会收到 SIGHUP 信号然后退出。所以正确姿势是加nohupnohup node wework-verify.js app.log 21 nohup的作用就是忽略挂断信号让进程在终端关闭后继续运行。5.5 pm2 启动报错提示 app 不存在如果 pm2 列表里空空如也但你又确实用 pm2 启动过可能你启动时没指定--namepm2 用脚本路径作为标识不同路径下启动会被认为是不同应用。建议统一规范启动时都指定名字pm2 start wework-verify.js --name wework-verify5.6 日志文件变得巨大长期跑的服务日志会越来越大磁盘被日志撑爆也是时有发生的事。日志文件过大还会导致日志写入变慢间接影响性能。建议定期清理或按天切割日志pm2 有内置的日志轮转功能pm2 install pm2-logrotate如果是 nohup 方式可以简单粗暴地在 crontab 里定期清空日志0 0 * * * truncate -s 0 /path/to/app.log这个命令不会删除文件只是把内容清零进程的日志句柄不受影响实测可用。6. 额外建议与其反复重启不如一开始就选对工具如果你现在用的是 nohup 方式我真心建议你迁移到 pm2。原因很简单nohup 方式下进程一旦崩溃不会自动恢复你只能手动登录服务器看日志排查。而 pm2 提供了守护进程的能力进程挂了会自动拉起还带了日志聚合、内存监控、开机自启等功能长期跑任务能省下大量精力。迁移过程不复杂先杀旧进程再执行pm2 start wework-verify.js --name wework-verify pm2 save pm2 startuppm2 save会把当前进程列表保存下来pm2 startup会生成开机自启脚本这样服务器重启之后 pm2 会自动拉起服务不需要人工干预。这里有一个实际体验过的细节必须提一下pm2 startup输出的那串命令是需要你在当前用户下执行的。直接复制它输出的完整命令粘贴回车即可不用动 sudo否则环境变量容易串掉。用上 pm2 之后更新文件就永远只需要一条命令了pm2 restart wework-verify再也不用手动找 PID、杀进程、重新拉起了。7. 我踩过几次坑之后的固定操作习惯现在我每次更新wework-verify.js操作流程已经固定下来了有点像肌肉记忆第一步node --check wework-verify.js做语法检查这是底线。 第二步cp备份原文件带时间戳。 第三步执行更新命令pm2 的话就是pm2 restart wework-verify。 第四步等两三秒pm2 status看状态pm2 logs wework-verify --lines 30扫一眼日志里有没有异常。 第五步实际触发一次业务功能确认新逻辑跑通。这套流程看起来多几步但每一步都是为了少踩一次坑。尤其是语法检查那一步真的能拦住一半以上的低级错误。如果你现在正被“更新文件没生效”这个问题困扰对照我上面说的方式先确认自己属于哪种启动方式再执行对应的重启命令基本就能解决。最后再说一个容易被忽略的小点如果你是通过 FTP 或者文件管理器直接上传替换服务器上的wework-verify.js上传完成后确认一下文件大小和本地是否一致。传输中断导致文件不完整的情况我也遇到过那时候代码看着没问题但一运行就是各种神奇的报错。用ls -l wework-verify.js看看大小再对比本地文件一眼就能识别出问题。
阅读完成 · 觉得有帮助?
咨询建站