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

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

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

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