V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
moment082
V2EX  ›  程序员

记录一次修改 PNPM 版本,部署 NextJs 服务时导致服务器崩溃的问题

  •  1
     
  •   moment082 · 20 小时 46 分钟前 · 1031 次点击

    最近在使用 NextJs 开发 DocFlow 协同编辑这个项目,运行了很久都没有问题,最近终于在部署方面出现了问题了,早上的时候发现 ssh 连不上了,一开始并没有太在意,但后来打开京东云控制台,好家伙真的好家伙:

    20251029202122

    真的小母牛坐飞机牛逼上天了!原来是 CPU 爆了,怪不得连接不上了,当然网站也 502 了:

    20251029202311

    那是什么原因呢,接下来就要开始慢慢排查了,既然 vscode 连不上,那我们就在官方提供的 ssh 来连接:

    20251029202432

    输入命令 htop ,罪魁祸首马上出现:

    20251029202653

    原来是 next-server 和 node (运行在 /home/DocFlow-Server/dist/main.js )占用了基本全部的 CPU ,那这个原因就很清楚了,那么接下来就可以排查了这个问题的原因了。

    首先,可以明确的一点是,之前一直都是同样的方式部署的,没有出现问题,但是为什么今天就一直出现这个问题呢,那肯定是在运行的进程出现了问题。

    我项目使用的是 pm2 部署的,那打个日志看看咯:

    20251029203101

    问题找到了,原来是 pm2 一直在重启,把内存全部占用了,具体是什么原因的已经不好查了,有可能是安装了一些依赖。我这个部署脚本是基本没问题的,至少能跑,现在查看这两天的 commit ,想起来有一个这样的操作:

    20251029204359

    那基本就可以确定是这个问题了。

    其他部署方案

    PM2 是一种流行的进程管理工具,适用于 Node.js 应用,尤其在小型项目和单机部署时很有效。然而,PM2 的部署流程存在一些局限性:

    1. 依赖管理和版本控制:PM2 需要手动确保服务器上安装正确的 Node.js 和 pnpm 版本。每次代码更新后,你还需要在服务器上重新 构建项目(执行 pnpm run build),这可能会导致生产环境与开发环境之间的不一致,并增加了维护工作。

    2. 服务中断问题:每次代码更新时,PM2 需要 重启应用 来使新版本生效。如果没有正确配置或管理,应用在重启过程中可能会停机一段时间,这对于高可用性要求较高的生产环境来说是个问题。

    与 PM2 相比,Docker 自动化部署 通过容器化解决了这些问题,提供了更简洁、更一致的部署流程,特别适用于云端和多环境部署。主要优势包括:

    1. 无需依赖管理和环境配置:Docker 将应用及其所有依赖、环境变量、构建过程封装在 Docker 镜像 中。这样,服务器上无需安装特定版本的 Node.js 或 pnpm ,避免了手动配置和版本不一致的问题。你只需要在 构建镜像时 配置好所有的依赖和环境,部署时无需再进行任何安装或构建操作。

    2. 代码问题不会影响运行:如果代码有问题,Docker 使得应用 不会受到当前部署的影响。因为 Docker 镜像已经包含了所有必要的依赖,部署失败时,原先的镜像仍然可以继续运行,确保生产环境不受影响。而在 PM2 部署 时,更新代码后需要重启应用,如果代码有问题,应用会直接停机,导致服务中断。

    3. 无缝的 CI/CD 集成:Docker 完美集成 CI/CD 流程。例如,使用 GitHub Actions ,你可以自动构建 Docker 镜像并推送到仓库。服务器只需要 拉取最新镜像,并启动新的容器。如果部署失败,不会影响当前运行的容器,你可以迅速恢复服务,且无需手动修复。相反,PM2 需要重新启动应用,且服务停机时需要手动修复代码。

    4. 快速回滚:由于 Docker 镜像的版本化机制,你可以轻松回滚到之前的稳定版本。即便遇到部署失败的情况,只需要拉取旧版本的镜像,应用立即恢复,不需要手动操作,这为应用提供了更高的可靠性。

    总结

    PM2 部署中,如果代码有问题,必须手动修复并重启应用,这可能会导致 服务中断,并影响用户体验。而且每次更新都需要在服务器上重新构建项目,这可能导致环境不一致,增加了部署的复杂性。

    Docker 部署则通过 容器化 确保应用和环境的一致性,部署失败时不会影响生产环境的运行,原有容器仍可继续工作,且通过 CI/CD 流程可以自动恢复和快速回滚,不需要人工干预。即使代码存在问题,原有的容器仍可保持正常服务,确保应用的高可用性。

    因此,对于生产环境,Docker 提供了比 PM2 更稳定、高效、自动化的部署方式,尤其适合大规模、高可用的应用部署。

    最后看到的问题是启动 PM2 一次性给我开了 3 个进程,资源相互抢占,导致服务器崩溃的,最后直接换成了 Docker 部署了

    16 条回复    2025-10-31 12:14:44 +08:00
    tyx1703
        1
    tyx1703  
       20 小时 14 分钟前 via iPhone   ❤️ 4
    省流:跟 pnpm 版本没有关系,pm2 启动多个进程,但端口冲突导致陷入无限重启
    moment082
        2
    moment082  
    OP
       20 小时 13 分钟前
    @tyx1703 之前一直运行着好好的,我也重新 build 了一遍了,再启动还是有问题,实在没搞懂什么原因
    tyx1703
        3
    tyx1703  
       19 小时 46 分钟前 via iPhone
    我猜大概率是两种情况之一:1. 以前 pm2 只起一个进程; 2. nextjs 某个依赖被升级,以前可能能自动发现可用端口,现在行为变了。
    skallz
        4
    skallz  
       19 小时 36 分钟前
    为什么用了 docker 就不能用 pm2 了呢?服务用 docker + pm2-runtime 很常见呀,而且这个根本原因和 pm2 也没关系,检查下项目吧,不然只是治标不治本,还是埋雷
    elboble
        5
    elboble  
       19 小时 28 分钟前
    supervisor 也有类似问题,restart 一个 python 的服务,会出现杀不死原进程,导致 cpu100%,必须手动杀死,然后就正常了。
    moment082
        6
    moment082  
    OP
       19 小时 27 分钟前
    @skallz 我后端服务跑了好几个 Docker 镜像了,本身 4 核 8g 的服务,NextJs 打包比较费内存,直接把这个交给 Github 来做了,我服务器直接拉镜像就好了
    moment082
        7
    moment082  
    OP
       19 小时 26 分钟前
    @tyx1703 这个我看也没有升级其他的,有可能是升级了 pnpm 版本,里面的 lock 文件的一些依赖变了导致的
    zhhbstudio
        8
    zhhbstudio  
       19 小时 22 分钟前
    1. 看上去是把 9.12 降级到了 9.4 吧
    2.1 复杂点就看看谁占用了 3000 端口,是不是旧的没停/杀完,我印象里 pm2 自己启动能多个进程端口是不冲突的
    2.2 直接重启服务器,然后启动看看
    moment082
        9
    moment082  
    OP
       19 小时 20 分钟前
    @zhhbstudio 这个都试过了,我试过把进程都删了,重新启动也是出现 3 个进程
    zhhbstudio
        10
    zhhbstudio  
       19 小时 9 分钟前
    @moment082 重启服务器试过没
    moment082
        11
    moment082  
    OP
       19 小时 4 分钟前
    @zhhbstudio 重启好几遍了,一重启完成就又爆了
    CHTuring
        12
    CHTuring  
       18 小时 45 分钟前
    如果不是特定 pnpm monorepo ,遇到问题用 yarn 就好了。
    guiyumin
        13
    guiyumin  
       18 小时 35 分钟前
    你需要服务器监控
    chenluo0429
        14
    chenluo0429  
       18 小时 14 分钟前 via Android
    @skallz 我理解有人会在 docker 里面用 pm2 ,但我不能理解为什么有人会在 docker 里面用 pm2
    Ketteiron
        15
    Ketteiron  
       17 小时 53 分钟前
    packageManger 是 node 的实验性功能,没事最好别用。
    我猜你们有个依赖只能在 pnpm9.4.0 下正常安装,甚至我大概已经猜出来包名了,它才是大雷。
    moment082
        16
    moment082  
    OP
       17 小时 35 分钟前
    @Ketteiron 不是,是我本地和服务端都是 9.4.0 ,之前 ai 把我这个改了,我没注意提交上去了
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   880 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 21:49 · PVG 05:49 · LAX 14:49 · JFK 17:49
    ♥ Do have faith in what you're doing.