使用systemd + pm2管理节点。js自托管服务:从“进程莫名死掉”到无人值守运行
前言
自托管服务最怕的不是配不出来,而是“跑起来之后某天轻轻挂了”。我维护着一个云服务器,上面跑着几个节点。js服务:订阅生成器、定时任务脚本、方向代理入口等。早期用裸奔,结果服务器重启、进程崩溃、OOM杀掉等各种情况轮番上演。本文总结了我把这套服务改造成systemd + pm2大规模托管、实现无人值守运行的完整过程和经验。nohup ... &
一、为什么是systemd + pm2两层?
| 层 | 负责 | 举例说明 |
|---|---|---|
| systemd | 系统级监控:开机自启动、崩溃拉起 | cloudflared、pm2本身 |
| 下午2 | 应用级监控:多进程管理、日志切割、内存超限重启 | 各节点。js业务进程 |
很多人只用其中一层。实际上pm2自己也是一个进程,服务器重启后如果没人拉起pm2,里面的业务全趴窝。正确姿势是:用systemd保pm2,用pm2保业务。
二、具体配置
1. pm2开机自启(踩坑最多的一步)
sudo env PATH=$PATH:/usr/local/bin pm2 startup systemd
pm2 save
坑点:如果pm2安装在而环境变量没有带全,生成的单元文件里PATH是错误的,重启后pm2起不来还报“ pm2: command not found”。解决办法就是像上面那样显式再执行。/usr/local/bin pm2 startup env PATH=...
2.业务进程托管
pm2 start app.js --name myapp --max-memory-restart 300M
pm2 save
-
--max-memory-restart:内存超限自动重启,防内存泄漏把整台机器拖垮。 -
pm2 save一定要执行,否则重启后进程列表为空。
3.日志切割
pm2默认把日志写进同一个文件,几周左右膨胀到几个GB 。安装一下切割模块:
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 14
三、排障三板斧
进程“看起来活着”不代表服务可用,我固定按这三步排查:
# ① 进程真的在跑吗?
pm2 ls
systemctl status pm2-root
# ② 端口真的在监听吗?
ss -tlnp | grep <端口>
# ③ 服务真的能响应吗?
curl -i http://127.0.0.1:<端口>/health
三层分别对应:进程层、网络层、应用层。任何一层断了,问题就锁定了那一段。我遇到过的典型案例:pm2显示进程在线,但端口没监听——原因是配置文件里端口被占用了,子进程启动失败被pm2反复重启,状态却一直显示在线。所以第②步ss检查端口监听是绝对不能省的。
四、额外建议
-
健康检查脚本 + cron:写一个每分钟执行的脚本,curl探测关键接口,失败就并记录日志,比仅依赖pm2的崩溃重启更稳定(能覆盖“进程活着但卡死”的情况)。
pm2 restart -
OOM优先级:在systemd单元里对关键进程设置
OOMScoreAdjust=-500,内存紧张时系统先杀其他。 -
重启后必查:养成服务器维护重启后执行的习惯,30秒确认所有服务恢复。
pm2 ls && ss -tlnp
结语
无人值守的核心不是“不挂”,而是“挂了能自己爬起来+挂的时候你能第一时间知道”。systemd保住pm2、pm2保住、健康检查兜底,三层下来我的服务器已经稳定运行数月没有人工干预过。希望思科配置能力能够帮助到同样在管理小型自托管服务的你。
- 点赞
- 收藏
- 关注作者
评论(0)