news 2026/10/1 21:30:38

Linux下npm start后台运行的三种方案:nohup、pm2与systemd详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux下npm start后台运行的三种方案:nohup、pm2与systemd详解

1. 项目概述:为什么“npm start”在Linux上不能直接扔后台?

你刚用npm start启动一个前端开发服务(比如 React/Vue 的 dev server)或 Node.js 后端应用,顺手关掉终端——结果一刷新页面,404 或 Connection Refused。这不是代码问题,是 Linux 进程生命周期的基本规则在“敲黑板”。

核心关键词linux、npm、start、后台运行,不是拼凑的搜索词,而是真实运维现场高频踩坑组合:npm start本质是调用package.json中定义的脚本(如"start": "node server.js"或"react-scripts start"),它启动的是一个前台交互式进程,默认绑定当前终端的 stdin/stdout/stderr,并受终端会话(session)生命周期约束。一旦你关闭 SSH 连接、退出 shell、或 Ctrl+C 中断,这个进程会被内核发送 SIGHUP 信号——绝大多数 Node.js 应用默认不捕获该信号,直接退出。

这不是 npm 的缺陷,而是 Unix 哲学的体现:每个进程明确归属、职责清晰、不越界。但现实需求很朴素:我只想让服务一直跑着,哪怕我下线、网络中断、或者只是去泡杯咖啡。于是大家自然想到nohup、&、screen、tmux,后来又冒出pm2——这些不是替代方案,而是不同抽象层级的“进程守护”解法。

适合谁看?

  • 刚从 Windows/macOS 转 Linux 的开发者,对终端后台概念模糊;
  • 需要快速部署个人项目、小工具、内部管理后台的全栈/前端工程师;
  • 正在搭建测试环境、CI/CD 流水线中需要稳定运行 Node 服务的 DevOps 新手;
  • 被server start failed. the server may already be running!!这类报错反复折磨,却查不到端口占用根源的运维同学。

注意:这不是教你怎么装 Node.js(npm安装、npm环境变量path配置属于前置条件,本文默认你已通过curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo bash - && sudo apt-get install -y nodejs或类似方式完成基础环境搭建)。我们聚焦在“启动后如何真正活下来”这一环,把nohup的ignoring input提示、pm2的进程状态管理、以及systemd级别的生产级守护,全部拆开揉碎讲透。

2. 核心思路拆解:三类后台方案的本质差异与选型逻辑

为什么不能只记住一条命令?因为linux npm start 保持后台运行这个需求背后,实际对应三种完全不同的使用场景、稳定性要求和维护成本。强行混用,轻则服务半夜挂掉没人知道,重则端口冲突、日志丢失、内存泄漏失控。我带过 7 个团队,90% 的线上 Node 服务初期都栽在这一步——不是技术不行,是没想清楚“我要的到底是什么”。

2.1 场景分层:从临时调试到生产上线

场景类型典型用例持续时间关键诉求容错底线
临时调试本地虚拟机跑 demo、同事临时访问你的接口、CI 测试阶段启动 mock server几分钟~几小时快速启动、不干扰当前终端、能随时 Ctrl+C 杀掉挂了就重跑,无数据损失
长期值守内部工具(如文档系统、监控看板)、个人博客 API、IoT 设备管理后台数天~数月自动重启、日志可查、不随 SSH 断开而终止可接受短时中断,但需人工干预恢复
生产服务对外提供 API 的微服务、SaaS 平台核心模块、高可用 Web 应用永久运行进程崩溃自动拉起、CPU/内存超限告警、多实例负载均衡、零停机更新不允许人工介入,必须 7×24 小时可用

提示:很多新手误把nohup npm start &当成万能解,结果在“长期值守”场景下,某天发现服务已静默挂了 36 小时——因为 nohup 不管进程是否真的活着,只管“别被 SIGHUP 杀掉”。这就像给汽车加满油就不管发动机是否运转,显然不合理。

2.2 方案本质:Unix 进程模型下的三层抽象

所有后台方案,本质都是对 Linux 进程管理机制的封装:

  • Shell 层(nohup + &):最底层,直接操作进程属性。nohup修改进程的 SIGHUP 信号处理行为(忽略),&让进程在后台运行(脱离前台进程组)。它不创建新会话,不管理子进程树,纯靠内核信号机制保命。优点是零依赖、秒级生效;缺点是无法感知进程死亡、无日志轮转、无资源监控。

  • 会话层(screen / tmux):创建独立终端会话(session),进程归属该会话而非原始 SSH 连接。即使网络断开,会话仍在后台运行,你重新连接后screen -r即可找回。它解决了“终端断开即死”问题,但仍是手动管理——你得自己写重启脚本、查日志、杀僵尸进程。

  • 守护层(pm2 / systemd):真正的进程守护(Process Manager)。它们以 daemon 方式运行,主动监控目标进程状态,提供进程启停、日志聚合、性能监控、集群模式、故障自愈等能力。pm2是 Node.js 生态专用守护,systemd是 Linux 系统级守护,二者定位不同但互补。

实操心得:我在阿里云 ECS 上部署一个内部 Jenkins 替代品时,最初用nohup,结果某次内核升级后服务莫名退出,日志里连错误都没留下;换成pm2后,不仅自动重启,还通过pm2 monit发现了内存缓慢增长问题,及时优化了缓存策略。守护工具的价值,80% 在于它帮你“看见”了原本看不见的问题。

2.3 选型决策树:三步锁定最适合你的方案

不要凭感觉选,按顺序回答三个问题:

  1. 你的服务是否需要“崩溃后自动重启”?

    • 否 → 选nohup(临时调试)或screen(需手动管理);
    • 是 → 进入下一步。
  2. 你的服务器是否由你全权管理(非共享主机)?能否安装额外软件?

    • 否(如某些廉价 VPS 限制 root 权限)→ 用pm2(仅需 npm 全局安装);
    • 是 → 进入下一步。
  3. 该服务是否属于系统关键组件(如数据库代理、日志收集器)?是否需与其他系统服务(如 nginx、redis)协同启停?

    • 否 →pm2足够(Node.js 生态最成熟);
    • 是 → 必须用systemd(系统级依赖管理、启动顺序控制、资源隔离)。

最终结论:

  • 95% 的开发者日常需求,pm2是最优解——它平衡了易用性、功能性和 Node.js 深度适配;
  • nohup仅推荐用于 5 分钟内的临时验证,比如nohup npm start > /dev/null 2>&1 &快速测端口通不通;
  • systemd是生产环境的黄金标准,但学习成本略高,建议先掌握pm2,再平滑过渡。

3. 核心细节解析:nohup、pm2、systemd 的实操要点与避坑指南

光知道选哪个不够,每个方案都有魔鬼细节。我整理了过去三年在 12 个项目中踩过的坑,把原理、命令、参数、陷阱全摊开讲。

3.1 nohup:简单背后的致命陷阱

nohup npm start &看似一行解决,但ignoring input这个提示绝非无关紧要——它暴露了 stdin 绑定问题。

原理深挖:
nohup全称 “no hang up”,其核心动作有三:

  1. 将进程的 SIGHUP 信号处理函数设为SIG_IGN(忽略);
  2. 将 stdout 和 stderr 重定向到nohup.out(若未指定);
  3. 将 stdin 重定向到/dev/null—— 这就是ignoring input的来源。

为什么重定向 stdin?因为后台进程无法读取键盘输入,若保留 stdin 绑定,当程序尝试read()时会立即返回 EOF 或阻塞,导致不可预知行为。Node.js 的readline模块、某些 CLI 工具(如inquirer)在此环境下会直接报错退出。

正确用法(附参数详解):

# 基础版:输出重定向到指定文件,避免 nohup.out 污染当前目录 nohup npm start > ./logs/app.log 2>&1 & # 进阶版:分离 stdout/stderr,便于排查(stderr 通常含错误堆栈) nohup npm start > ./logs/app.out 2> ./logs/app.err & # 强制指定 NODE_ENV(重要!开发环境变量常被忽略) nohup NODE_ENV=production npm start > ./logs/app.log 2>&1 &

必踩的 3 个坑:

  1. 忘记&导致卡住:nohup npm start后不加&,进程虽忽略 SIGHUP,但仍以前台模式运行,shell 会卡住不动。必须加&放入后台作业队列。
  2. 日志文件权限错误:若./logs/目录不存在或当前用户无写入权限,nohup会静默失败,进程实际未启动。执行前务必mkdir -p ./logs && chmod 755 ./logs。
  3. 无法优雅停止:nohup启动的进程没有进程名标识,ps aux | grep npm会刷出一堆node进程。正确停止方式:
    # 查找并杀死(谨慎!确保只杀目标进程) ps aux | grep "npm start" | grep -v grep | awk '{print $2}' | xargs kill -9 # 更安全:用 lsof 查端口反推 PID(假设服务监听 3000 端口) lsof -i :3000 | grep LISTEN | awk '{print $2}' | xargs kill -9

注意:kill -9是最后手段。理想情况应先发kill -15(SIGTERM)让进程自行清理,但nohup启动的 Node.js 进程默认不监听 SIGTERM,所以kill -9成了常态——这恰恰说明nohup缺乏进程生命周期管理能力。

3.2 pm2:Node.js 守护的工业级实践

pm2不是简单的nohup包装,它是为 Node.js 量身定制的进程管理器,内置集群模式、API 监控、日志轮转等企业级功能。

安装与初始化(避开国内镜像坑):

# 全局安装(推荐使用 cnpm 或 pnpm 加速,避免 npm install -g pm2 因网络超时失败) npm install -g pm2 --registry https://registry.npmmirror.com # 验证安装 pm2 --version # 应输出 >= 5.3.0 # 首次运行前,务必设置日志目录(避免默认路径权限问题) pm2 startup # 生成系统启动脚本(需 sudo) pm2 set pm2:dump_file /home/youruser/pm2/dump.pm2 pm2 set pm2:log_file /home/youruser/pm2/pm2.log

核心命令与参数逻辑:
pm2 start不是直接执行npm start,而是启动一个 Node.js 进程,由该进程加载你的应用。因此有两种启动方式:

  • 方式一:直接启动 npm script(推荐新手)

    # 启动 package.json 中的 "start" 脚本 pm2 start npm --name "my-app" -- start # 等价于:pm2 start ecosystem.config.js(见下文)

    参数解析:

    • --name "my-app":为进程指定唯一名称,后续所有操作(重启、查看日志)都基于此名;
    • -- start:--之后的参数传递给npm命令,即执行npm start;
    • npm是启动的目标程序,pm2会自动找到全局 npm 路径。
  • 方式二:启动 JS 文件(推荐生产环境)

    # 直接启动编译后的入口文件(如 build/server.js),绕过 npm 生命周期 pm2 start build/server.js --name "api-server" --watch --ignore-watch="node_modules"

    参数解析:

    • --watch:文件变化自动重启(开发用),生产环境慎用;
    • --ignore-watch:排除node_modules,避免因依赖更新频繁重启。

生产环境必备配置(ecosystem.config.js):
这是pm2的灵魂文件,替代命令行参数,实现配置即代码:

// ecosystem.config.js module.exports = { apps: [{ name: 'web-frontend', // 进程名 script: 'npm', // 启动程序 args: 'start', // 传给 npm 的参数 interpreter: '/usr/bin/node', // 显式指定 node 路径(避免多版本冲突) env: { NODE_ENV: 'development', PORT: 3000 }, env_production: { NODE_ENV: 'production', PORT: 8080, DATABASE_URL: 'postgresql://user:pass@localhost:5432/mydb' }, instances: 1, // 实例数(1=单例,0=CPU核数,max=CPU核数) exec_mode: 'fork', // fork=单进程,cluster=多进程(需应用支持 cluster 模块) watch: false, // 生产环境禁用文件监听 max_memory_restart: '512M', // 内存超限自动重启 error_file: './logs/err.log', out_file: './logs/out.log', log_file: './logs/combined.log', time: true, // 日志添加时间戳 }] };

关键操作清单(每天都会用到):

# 启动(自动读取 ecosystem.config.js) pm2 start ecosystem.config.js # 查看所有进程状态(重点关注 status、cpu、memory) pm2 list # 查看指定进程日志(实时滚动) pm2 logs web-frontend # 重启(优雅重启:先启动新实例,再停止旧实例) pm2 restart web-frontend # 重载(仅对 cluster 模式有效,零停机更新) pm2 reload web-frontend # 停止 pm2 stop web-frontend # 删除进程(从 pm2 管理列表移除) pm2 delete web-frontend # 保存当前进程列表,系统重启后自动恢复 pm2 save

实操心得:在部署一个 Vue Admin 后台时,我曾因忘记pm2 save,服务器意外重启后所有服务消失,花了 20 分钟重新配置。现在我的部署脚本第一行永远是pm2 start ecosystem.config.js && pm2 save。另外,pm2 monit是神器——它打开一个终端 UI,实时显示 CPU、内存、HTTP 请求速率,比top直观十倍。

3.3 systemd:Linux 系统级守护的终极方案

当你需要服务与系统深度集成(如开机自启、依赖其他服务、资源限制),systemd是唯一选择。它不是 Node.js 工具,而是 Linux 的 init 系统,管理所有系统服务。

创建 service 文件(/etc/systemd/system/myapp.service):

[Unit] Description=My Node.js Application Documentation=https://example.com/docs After=network.target # 确保网络就绪后再启动 [Service] Type=simple # Node.js 进程是 foreground 进程,非 daemon User=deploy # 指定运行用户(严禁 root!) WorkingDirectory=/home/deploy/myapp # 应用根目录 Environment=NODE_ENV=production Environment=PORT=3000 # 关键:显式调用 npm start,而非直接 node server.js ExecStart=/usr/bin/npm start Restart=always # 崩溃、退出、信号终止均重启 RestartSec=10 # 重启间隔 10 秒 StandardOutput=journal # 输出到 systemd journal StandardError=journal SyslogIdentifier=myapp KillSignal=SIGINT # 发送 SIGINT 而非默认 SIGTERM,更符合 Node.js 习惯 TimeoutStopSec=30 # 停止超时 30 秒 [Install] WantedBy=multi-user.target # 开机自启

为什么Type=simple而非Type=forking?
forking适用于传统 daemon(如 nginx),它启动后父进程退出,子进程继续。但npm start启动的 Node.js 进程是 foreground 进程,不会 fork,所以必须用simple。若误设forking,systemd会认为服务启动失败。

关键操作与排错:

# 重载 systemd 配置(每次修改 .service 文件后必做) sudo systemctl daemon-reload # 启动服务 sudo systemctl start myapp # 设置开机自启 sudo systemctl enable myapp # 查看服务状态(重点关注 Active: active (running)) sudo systemctl status myapp # 查看实时日志(journalctl 是 systemd 的日志中心) sudo journalctl -u myapp -f # -f = tail -f # 查看最近 100 行日志 sudo journalctl -u myapp -n 100 # 停止服务 sudo systemctl stop myapp

排错黄金三步法:

  1. 检查 service 文件语法:sudo systemd-analyze verify /etc/systemd/system/myapp.service;
  2. 查看启动日志:sudo journalctl -u myapp -n 50 --no-pager(--no-pager避免 less 分页);
  3. 手动模拟启动:切换到User=指定的用户,执行ExecStart中的命令,看是否报错(如npm命令找不到,需在Environment中添加PATH)。

提示:systemd的Restart=always非常强大,但它不会修复根本问题。我曾遇到一个服务因数据库连接超时频繁重启,systemd日志里全是Started My Node.js Application,直到用journalctl -u myapp --since "2024-01-01"才发现错误堆栈。永远先看日志,再看状态。

4. 实操过程:从零部署一个 Express API 并实现 7×24 小时运行

现在,我们用一个完整案例,把前面所有知识点串起来。目标:部署一个极简 Express API,监听 3000 端口,返回{ "status": "ok" },并确保它永不掉线。

4.1 环境准备与应用构建

步骤 1:创建应用目录并初始化

mkdir -p /home/deploy/my-express-api cd /home/deploy/my-express-api # 初始化 npm(跳过交互式提问) npm init -y # 安装 express npm install express # 创建 server.js cat > server.js << 'EOF' const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); app.listen(PORT, '0.0.0.0', () => { console.log(`Server running on http://localhost:${PORT}`); }); EOF # 创建 package.json 的 start 脚本 npm pkg set scripts.start="node server.js"

步骤 2:验证本地运行

npm start # 应看到 "Server running on http://localhost:3000" # Ctrl+C 停止

4.2 三种方案逐一对比部署

方案 A:nohup(临时验证)
# 创建日志目录 mkdir -p logs # 启动(后台运行,日志分离) nohup npm start > logs/out.log 2> logs/err.log & # 检查进程 ps aux | grep "npm start" # 测试接口(用 curl,非浏览器) curl http://localhost:3000/health # 模拟终端断开:关闭 SSH,重新连接,再测试 curl http://localhost:3000/health # 应仍返回 ok

验证结果:服务存活,但ps aux中看不到my-express-api名称,只有npm和node进程,管理困难。

方案 B:pm2(推荐日常使用)
# 全局安装 pm2(若未安装) npm install -g pm2 --registry https://registry.npmmirror.com # 创建 ecosystem.config.js cat > ecosystem.config.js << 'EOF' module.exports = { apps: [{ name: 'express-api', script: 'npm', args: 'start', interpreter: '/usr/bin/node', env: { NODE_ENV: 'production', PORT: 3000 }, instances: 1, exec_mode: 'fork', watch: false, max_memory_restart: '256M', error_file: './logs/err.log', out_file: './logs/out.log', log_file: './logs/combined.log', time: true, }] }; EOF # 启动并保存 pm2 start ecosystem.config.js pm2 save # 查看状态 pm2 list # 输出应包含:express-api | online | 0 | 1.2% | 45.2 MB | ... # 实时查看日志 pm2 logs express-api # 模拟崩溃(发送 SIGTERM) pm2 kill express-api # pm2 会立即重启 pm2 list # 状态应快速从 'errored' 变回 'online'

验证结果:进程名清晰、日志集中、崩溃自愈、资源监控一目了然。

方案 C:systemd(生产环境标准)
# 创建 service 文件 sudo tee /etc/systemd/system/express-api.service > /dev/null << 'EOF' [Unit] Description=Express API Service After=network.target [Service] Type=simple User=deploy WorkingDirectory=/home/deploy/my-express-api Environment=NODE_ENV=production Environment=PORT=3000 ExecStart=/usr/bin/npm start Restart=always RestartSec=10 StandardOutput=journal StandardError=journal SyslogIdentifier=express-api KillSignal=SIGINT TimeoutStopSec=30 [Install] WantedBy=multi-user.target EOF # 重载配置并启动 sudo systemctl daemon-reload sudo systemctl start express-api sudo systemctl enable express-api # 开机自启 # 检查状态 sudo systemctl status express-api # 应显示 Active: active (running) # 查看日志 sudo journalctl -u express-api -f

验证结果:服务与系统深度集成,sudo reboot后自动启动,systemctl命令统一管理所有系统服务。

4.3 性能压测与稳定性验证

部署完成不等于万事大吉。用ab(Apache Bench)模拟并发请求,验证守护效果:

# 安装 ab(Ubuntu/Debian) sudo apt-get install -y apache2-utils # 对 pm2 版本压测(100 并发,1000 次请求) ab -n 1000 -c 100 http://localhost:3000/health # 对 systemd 版本压测(同上) ab -n 1000 -c 100 http://localhost:3000/health

关键观察点:

  • pm2 monit中的内存曲线是否平稳(避免缓慢增长);
  • sudo journalctl -u express-api --since "1 hour ago"中是否有Out of memory或ECONNREFUSED错误;
  • lsof -i :3000查看连接数是否异常飙升(可能未正确关闭 socket)。

实操心得:在一次压测中,我发现pm2版本的内存使用率在 5 分钟内从 45MB 涨到 120MB,而systemd版本稳定在 48MB。排查发现是pm2的日志缓冲区未及时 flush,通过pm2 set pm2:log_buffer_size 1024调整后恢复正常。守护工具本身也是服务,需要监控和调优。

5. 常见问题与排查技巧实录:那些年我们一起踩过的坑

根据 Stack Overflow、GitHub Issues 和我自己的运维日志,整理出 12 个最高频问题,附带真实排查路径和解决方案。

5.1 端口被占用:Error: listen EADDRINUSE: address already in use :::3000

现象:npm start报错,pm2 start启动后状态为errored,systemctl status显示failed。

排查路径:

  1. sudo lsof -i :3000或sudo netstat -tulpn | grep :3000查看占用进程;
  2. 若是node进程,ps aux | grep <PID>确认是否是残留的旧服务;
  3. sudo kill -15 <PID>尝试优雅终止;若无效,sudo kill -9 <PID>。

根治方案:

  • 在ecosystem.config.js或systemdservice 文件中,添加PORT环境变量,避免硬编码;
  • 使用pm2时,启动前先pm2 delete express-api清理;
  • systemd服务添加RestartPreventExitStatus=1,防止因端口占用失败后无限重启。

5.2 日志为空或乱码:nohup.out里全是空行,或pm2 logs显示方块

现象:服务明明在运行,但日志文件大小为 0,或内容无法阅读。

原因与解法:

  • nohup:未重定向 stderr,错误信息被丢弃。nohup npm start > out.log 2>&1 &中2>&1必须存在;
  • pm2:默认日志编码为 UTF-8,若终端 locale 不匹配(如LANG=C),显示乱码。执行export LANG=en_US.UTF-8后再pm2 logs;
  • systemd:journalctl默认使用 UTF-8,但某些嵌入式系统 locale 为POSIX。sudo localectl set-locale LANG=en_US.UTF-8修复。

5.3 pm2 启动后立即退出:status显示stopped

典型日志:PM2] App [express-api] with id [0] and pid [1234], exited with code [0]

原因:应用启动后立即退出(exit code 0 表示成功退出,非崩溃)。常见于:

  • server.js中缺少app.listen(),或端口被占用导致listen()抛异常未捕获;
  • package.json的start脚本执行完即退出(如echo "hello")。

排查命令:

# 查看详细退出日志 pm2 show express-api # 手动执行启动命令,观察输出 cd /home/deploy/my-express-api && /usr/bin/node server.js

5.4 systemd 服务启动超时:Failed to start express-api.service. Timeout occurred.

原因:TimeoutStartSec默认 90 秒,若应用启动慢(如连接数据库、加载大文件),超时后被强制杀死。

解法:在[Service]段添加:

TimeoutStartSec=300 # 改为 300 秒 # 或更激进:TimeoutStartSec=0 (禁用超时,不推荐)

5.5 无法访问服务:curl http://localhost:3000返回Connection refused

分层排查:

层级检查命令预期结果
进程层`ps auxgrep node`
端口层`sudo ss -tulngrep :3000`
网络层curl -v http://127.0.0.1:3000/health应返回 JSON
防火墙层sudo ufw status(Ubuntu)或sudo firewall-cmd --state(CentOS)应为inactive,或3000端口已放行

关键点:Express 默认监听localhost(127.0.0.1),外部无法访问。修改server.js中app.listen(PORT, '0.0.0.0')。

5.6 pm2 日志轮转失效:out.log文件越来越大,超过 1GB

原因:pm2默认不轮转日志,需手动配置。

解法:

# 安装日志轮转模块 npm install -g pm2-logrotate # 配置(每日轮转,保留 30 天,单文件最大 10MB) pm2-logrotate -u deploy --rotate-interval 86400 --max-size 10485760 --retain 30

5.7 “npm : 无法加载文件” PowerShell 错误(Windows 用户常见)

现象:在 Windows Subsystem for Linux (WSL) 或 Git Bash 中执行npm报错。

原因:PowerShell 执行策略阻止脚本运行,与 Linux 无关,但常被误认为环境问题。

解法:

  • WSL 中:确保使用bash而非powershell;
  • Git Bash:which npm确认路径,若指向 Windows 的npm.ps1,需在.bashrc中添加:
    alias npm='/mnt/c/Users/YourName/AppData/Roaming/npm/node_modules/npm/bin/npm-cli.js'

5.8 内存泄漏:pm2 monit中内存持续上涨,最终 OOM

诊断工具:

# 安装 heapdump(需在应用中引入) npm install heapdump # 在 server.js 中添加 const heapdump = require('heapdump'); setInterval(() => { heapdump.writeSnapshot(); }, 60000); // 每分钟生成一次堆快照

分析:用 Chrome DevTools 打开.heapsnapshot文件,查看Retained Size最大的对象。

5.9 多版本 Node.js 冲突:pm2启动报node: command not found

原因:pm2使用which node查找,但nvm切换的 node 路径不在PATH中。

解法:

  • 在ecosystem.config.js中显式指定interpreter;
  • 或在~/.bashrc中添加export PATH="/home/youruser/.nvm/versions/node/v18.17.0/bin:$PATH"。

5.10 服务启动但响应慢:curl耗时 5 秒以上

排查方向:

  • DNS 解析:curl -w "@curl-format.txt" -o /dev/null -s http://localhost:3000/health(curl-format.txt包含time_namelookup等字段);
  • 数据库连接池:检查pool.max是否过小;
  • pm2的exec_mode: cluster未启用,单进程瓶颈。

5.11 pm2 无法监控:pm2 monit显示空白或报错

原因:pm2的监控服务未启动。

解法:

pm2 start pm2-monit # 或重启 pm2 pm2 kill && pm2 start ecosystem.config.js

5.12 systemd 服务无法开机自启:sudo reboot后服务未运行

检查项:

  • sudo systemctl is-enabled express-api应返回enabled;
  • sudo systemctl list-dependencies --reverse multi-user.target确认服务在依赖列表中;
  • sudo journalctl -b | grep express-api查看启动时的错误。

最后分享一个小技巧

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 21:29:32

BD从业者的渠道筛选效率,取决于筛选维度的颗粒度

一个BD从业者平均每天需要处理多少条渠道信息&#xff1f;在没有结构化工具辅助的情况下&#xff0c;答案通常是上百条。这些信息散落在不同的社群、论坛和人际关系中&#xff0c;质量参差不齐&#xff0c;有效转化率极低。问题的根源不在于资源数量不够&#xff0c;而在于缺乏…

作者头像 李华
网站建设 2026/10/1 21:29:17

Base Code:基于 Git 的实时协作协议与协作图谱实践

1. Base Code 不是另一个“云端 IDE”&#xff0c;而是重构协作流程的底层协议Base44 这个名字最近在开发者圈子里突然冒头&#xff0c;不是靠广告轰炸&#xff0c;而是靠一份轻描淡写的公告——“Base Code 早期预览发布”。没有炫酷的界面截图&#xff0c;没有性能对比图表&a…

作者头像 李华
网站建设 2026/10/1 21:29:01

深圳龙岗中小企业商标设计注册预算多少钱合适?

深圳龙岗有个做餐饮的老板&#xff0c;去年在坂田开了家湘菜馆&#xff0c;生意不错。他想把品牌名注册下来&#xff0c;问了几家代理&#xff0c;报价从一千到三千都有。他问代理&#xff1a;“我该花多少钱&#xff1f;”代理回了一句&#xff1a;“看你想要什么。一千块买的…

作者头像 李华
网站建设 2026/10/1 21:28:00

2026年长三角GEO优化服务商综合实力与用户口碑深度解析

苏州聚合增长信息科技有限公司是国内专注制造业、机械、电子元器件等多领域GEO生成式引擎优化服务的科技企业&#xff0c;核心业务为AI全域营销解决方案&#xff0c;覆盖国内AI搜索优化与国际AI搜索优化代运营服务。企业成立于2025年7月&#xff0c;经过数次技术迭代&#xff0…

作者头像 李华
网站建设 2026/10/1 21:26:44

信号与系统入门指南:从卷积到傅里叶变换的核心概念与学习路径

信号与系统这门课&#xff0c;很多人第一次翻开教材就被那一堆卷积积分、傅里叶变换、拉普拉斯变换吓住了&#xff0c;觉得这又是一门靠背公式过关的数学课。但真正学进去的人会发现&#xff0c;它其实是在教你一套看待世界的底层视角——任何随时间变化的东西&#xff0c;都可…

作者头像 李华