node 进程管理工具 pm2 的详细说明 —— 一步一步配置 Ubuntu Server 的 NodeJS 服务器详细实录 7
前言
我以 Ubuntu Server 打造的 NodeJS 服务器为主题的系列文章,经过五篇博客,我们顺利的 安装了 ubuntu server 服务器,并且配置好了 ssh 免密登录服务器,安装好了 服务器常用软件安装, 配置好了 zsh 和 vim 以及 通过 NVM 安装好Nodejs,还有PNPM包管理工具 ,最后,还给服务器 安装和配置 Nginx 和 Mysql 。至此,我们的基于 Ubuntu Server 打造的 NodeJS 服务器的基础已经全部完成了。
今天,我来写这个系列的最后一篇文章,就是 NodeJS 的进程管理软件, pm2 的相关内容。
为什么要使用 pm2 管理 node 进程
当我们在服务器终端内输入 pnpm start
命令,就可以启动 NodeJS 的服务了。但是,随着我们终端的关闭,这个服务也会随之关闭。
为了使进程可以在终端关闭后,依然在后台运行,我们可以使用 nohup pnpm start > /dev/null 2>&1 &
这样的命令来执行。
当然,我们也可以开启一个 tmux
来解决这些问题,在开发环境上这么搞是没有啥的,但是在生产环境,这样搞就有点过于简陋了。
PM2 是 Node.js 生态中最主流的进程管理工具,主要特性包括:
进程守护
- 自动重启崩溃应用,保障服务高可用性。
负载均衡
- 通过集群模式(cluster 模块)充分利用多核 CPU,支持零秒停机重载36。
- 示例命令:pm2 start app.js -i 4(启动 4 个进程)。
日志管理
- 自动收集日志,支持轮转分割与实时查看(pm2 logs)。
监控与告警
- 实时监控 CPU/内存使用(pm2 monit),支持异常报警。
开机自启动
- 通过 pm2 startup 生成系统服务脚本。
跨语言支持
- 兼容 Python、Ruby 等非 Node.js 应用(需配置虚拟环境)。
通过使用 pm2, 我们可以更方便,更直观的管理我们的 NodeJS 进程。
pm2 的安装
pm2 的官方网站是 https://pm2.keymetrics.io/,我们根据官方网站的介绍,在服务器上运行安装命令,如下:
npm install pm2 -g
pm2 运行一个项目
我不能拿我真实的项目来演示,因此,我选择运行我开发并开源的一款前端 Mock 工具来进行演示。
项目地址: https://github.com/fengcms/simple-mock
将项目部署到服务器上
我比较习惯,将我们的代码部署在 /srv
目录上。因为 Linux 的根目录下有众多的目录,各有各的作用,这里不详细介绍。一般情况下,大家都习惯把项目部署在 srv
和 var
目录下,大家根据自己的习惯部署即可。
但是,Ubuntu 系统默认这些目录,都是 root 用户权限,因此,我们需要将目录的用户权限进行调整,否则,我们就需要一直 sudo
了。
我们执行下面的命令,来进行文件夹用户权限的调整
sudo chown fungleo:fungleo /srv
调整后,如下图所示:
好,我们进入 srv 目录,并创建 web
文件夹,然后拉取我上面的项目,并安装依赖
# 进入 /srv 目录
cd /srv
# 创建 web 目录,用于存储我们的各种服务
mkdir web
# 进入 web 目录
cd web
# 拉取我准备部署的项目
git clone https://github.com/fengcms/simple-mock
# 进入项目目录
cd simple-mock
# 安装依赖
pnpm install
# 启动项目
pnpm start
运行结果如下图所示:
用 pm2 启动项目
通过上面的命令,我们已经顺利的在服务器启动项目了,说明我们的项目没有问题。下面,我们 ctrl + c
终止测试运行,准备用 pm2 来启动项目吧。
启动命令如下:
pm2 start "pnpm start" --name "simple-mock"
其中 pm2 start
为 pm2 的启动命令,"pnpm start"
为我们项目的启动命令,--name "simple-mock"
表示,我们将这个进程命名为 simple-mock
。
启动后,会立即返回一个当前的进程托管的列表,如下图所示:
从上图,我们可以看到我们命名为 simple-mock
而,id 为 0 的这个进程。
我们打开浏览器,访问服务器上的这个服务,就可以看到,项目已经正常运行了。
pm2 常用命令
最后,我们来总结一下 pm2 的常用命令:
# 安装
npm install -g pm2
# 更新
pm2 update## 启动服务
# 启动 app.js 文件
pm2 start app.js
# 启动 npm 脚本
pm2 start "npm run start"
# 启动 Python 脚本
pm2 start python-app.py
# 启动 Shell 脚本
pm2 start bashscript.sh## 高级参数
# 自定义进程名称
pm2 start app.js --name "my-app"
# 监听文件改动自动重启
pm2 start app.js --watch
# 启动 4 个集群实例
pm2 start app.js -i 4## 进程管理
# 查看所有进程状态
pm2 list
# 停止指定进程
pm2 stop <id|name>
# 重启进程
pm2 restart <id|name>
# 删除进程
pm2 delete <id|name>
# 零停机重载集群应用
pm2 reload all ## 日志与监控
# 查看实时日志
pm2 logs
# 查看最近 100 行日志
pm2 logs --lines 100
# 显示 CPU/内存占用面板
pm2 monit
# 查看进程详细信息
pm2 show <id|name> ## 系统集成
# 生成开机自启命令
pm2 startup
# 保存当前进程列表
pm2 save
# 恢复已保存的进程
pm2 resurrect
需要注意的是,zsh 不支持 pm2 命令的 tab 补全,所以,需要各位记住这些常用命令哦!如果记不住的话,收藏这篇博客作为你的肘后方吧!
小结
好的,这一个基于Ubuntu Server 打造的 NodeJS 服务器为主题的系列文章终于到这里是写完了,前前后后写了三四天。虽然都是些基础的东西,但是我相信对于各位看官来说,还是有一定的增益的。
我写博客的目的主要是为了自己和自己团队的成员看,涉及的内容一般都比较基础一些。为了让我团队的新进成员能够一看就明白,可能文风偏啰嗦了一些,希望各位看官见谅。
最后为了鼓励我自己能够继续写下去,各位看看一定要多多点赞收藏,关注留言哈!谢谢大家!
本系列文章导航
《PVE虚拟机 安装 Ubuntu Server 系统》
《SSH 配置,让我们远程连上虚拟机》
《服务器软件更新,以及常用软件安装》
《配置服务器终端环境 zsh , oh my zsh, vim》
《NVM 安装 NodeJS环境,以及 PNPM 的安装》
《Nginx 和 Mysql 的安装和配置》
《pm2 服务端进程管理的使用和配置》
相关文章:

node 进程管理工具 pm2 的详细说明 —— 一步一步配置 Ubuntu Server 的 NodeJS 服务器详细实录 7
前言 我以 Ubuntu Server 打造的 NodeJS 服务器为主题的系列文章,经过五篇博客,我们顺利的 安装了 ubuntu server 服务器,并且配置好了 ssh 免密登录服务器,安装好了 服务器常用软件安装, 配置好了 zsh 和 vim 以及 通过 NVM 安装…...

Flask与Celery 项目应用(shared_task使用)
目录 1. 项目概述主要功能技术栈 2. 项目结构3. 环境设置创建虚拟环境并安装依赖主要依赖 4. 应用配置Flask应用初始化 (__init__.py)Celery应用初始化 (make_celery.py) 5. 定义Celery任务 (tasks.py)任务说明 6. 创建API端点 (views.py)API端点说明 7. 前端界面 (index.html)…...
Fetch API 使用详解:Bearer Token 与 localStorage 实践
Fetch API:现代浏览器内置的用于发送 HTTP 请求的 API,Bearer Token:一种基于令牌的身份验证方案,常用于 JWT 认证,localStorage:浏览器提供的持久化存储方案,用于在客户端存储数据。 token是我…...
vue3 vite.config.js 引入bem.scss文件报错
[sass] Can’t find stylesheet to import. ╷ 1 │ use “/bem.scss” as *; │ ^^^^^^^^^^^^^^^^^^^^^^ ╵ src\App.vue 1:1 root stylesheet 分析 我们遇到了一个在Vue3项目中使用Vite时,在vite.config.js中引入bem.scss文件报错的问题。错误信息指出在App.vue…...

二叉树-226.翻转链表-力扣(LeetCode)
一、题目解析 翻转可以理解为树的左右子树交换,从根到叶子节点,但是这里交换的是链接的指针,而不是单纯的交换值,当出现nullptr时,也是可以交换链接的,交换值的话就不行了。 二、算法原理 依旧的递归&…...

HarmonyOS Next 弹窗系列教程(3)
HarmonyOS Next 弹窗系列教程(3) 选择器弹窗 (PickerDialog) 介绍 选择器弹窗通常用于在用户进行某些操作(如点击按钮)时显示特定的信息或选项。让用户可以进行选择提供的固定的内容。 以下内容都属于选择器弹窗: …...
编程笔记---问题小计
编程笔记 qml ProgressBar 为什么valuemodel.progress / 100 在QML中,ProgressBar的value属性用于表示进度条的当前进度值,其范围通常为0到1(或0%到100%)。当使用model.progress / 100来设置value时,这样做的原因是为…...

【docker】Windows安装docker
环境及工具(点击下载) Docker Desktop Installer.exe (windows 环境下运行docker的一款产品) wsl_update_x64 (Linux 内核包) 前期准备 系统要求2: Windows 11:64 位系统&am…...

无人机避障——感知部分(Ubuntu 20.04 复现Vins Fusion跑数据集)胎教级教程
硬件环境:NVIDIA Jeston Orin nx 系统:Ubuntu 20.04 任务:跑通 EuRoC MAV Dataset 数据集 展示结果: 编译Vins Fusion 创建工作空间vins_ws # 创建目录结构 mkdir -p ~/vins_ws/srccd ~/vins_ws/src# 初始化工作空间…...
人工智能--大型语言模型的存储
好的,我现在需要回答用户关于GGUF文件和safetensors文件后缀的差别的问题。首先,我得先确认这两个文件格式的具体应用场景和它们各自的优缺点。用户可能是在处理大模型时遇到了这两种文件格式,想了解它们的区别以便正确使用。 首先ÿ…...
OD 算法题 B卷【删除字符串中出现次数最少的字符】
文章目录 删除字符串中出现次数最少的字符 删除字符串中出现次数最少的字符 实现删除字符串中出现次数最少的字符,若(最少的)有多个字符出现次数一样,则都删除。输出删除后的字符串,其他字符保持原有顺序;…...

如何安装并使用RustDesk
参考: 搭建 RustDesk Server:打造属于自己的远程控制系统,替代 TeamViewer 和 ToDesk! 向日葵、ToDesk再见!自己动手,自建RustDesk远程服务器真香! 通俗易懂:RustDesk Server的搭…...

机器学习——随机森林算法
随机森林算法是一种强大的树集成算法,比使用单个决策树效果要好得多。 以下是生成树集成的方法:假设有一个大小为m的训练集,然后对于b1到B,所以执行B次,可以使用有放回抽样来创建一个大小为m的训练集。所以如果有10个…...

【从零学习JVM|第二篇】字节码文件
前言: 通过了解字节码文件可以帮助我们更容易的理解JVM的工作原理,所以接下来,我们来介绍一下字节码文件。 目录 前言: 正确的打开字节码文件 字节码文件组成 1. 魔数(Magic Number) 2. 版本号&…...

Fractal Generative Models论文阅读笔记与代码分析
何恺明分型模型这篇文章在二月底上传到arXiv预出版网站到现在已经过了三个月,当时我也听说这篇文章时感觉是大有可为,但是几个月不知道忙啥了,可能错过很多机会,但是亡羊补牢嘛,而且截至目前,该文章应该也还…...
软件测试—学习Day11
今天学习下兼容性 1.App兼容性常见问题 以下是关于 App 兼容性问题的常见举例,涵盖界面展示、操作逻辑、性能差异三大维度,涉及不同系统、设备及网络环境的兼容性场景: 一、界面展示问题 界面展示兼容性问题主要由操作系统版本差异、屏幕…...

OGG-01635 OGG-15149 centos服务器远程抽取AIX oracle11.2.0.4版本
背景描述 有一套ogg远程抽取的环境,源端是AIX7.1环境的oracle 11.2.0.4版本的数据库,中间是OGG抽取服务器,目标端是centos 7.9环境的oracle 19c。 采用集成模式远程抽取源端数据正常,但是经典模式远程抽取源数据的时候抽取进程启…...

Kotlin REPL初探
文章目录 1. Kotlin REPL 简介2. 在命令行中玩Kotlin REPL2.1 下载Kotlin编译器压缩包2.2 安装配置Kotlin编译器2.3 启动Kotlin交互式环境2.4 在命令行玩Kotlin REPL 3. 在IDEA里玩Kotlin REPL3.1 打开Kotlin REPL窗口3.2 在Kotlin REPL窗口玩代码 4. Kotlin REPL 的优势 1. Ko…...

git引用概念(git reference,git ref)(简化对复杂SHA-1哈希值的管理)(分支引用、标签引用、HEAD引用、远程引用、特殊引用)
文章目录 **引用的本质**1. **引用是文件**2. **引用的简化作用** **引用的类型**1. **分支引用(Branch References)**2. **标签引用(Tag References)**3. **HEAD 引用**4. **远程引用(Remote References)*…...

Github 2025-06-07 Rust开源项目日报Top10
根据Github Trendings的统计,今日(2025-06-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Dart项目1TypeScript项目1RustDesk: 用Rust编写的开源远程桌面软件 创建周期:1218 天开发语言:Rust, Dart协议类型:GNU Affero Ge…...
gorm 配置数据库
介绍 GORM 是 Go 语言中最流行的 ORM(对象关系映射)库之一,基于数据库操作的封装,提供类似 Django ORM / SQLAlchemy 的开发体验。 特性描述支持多种数据库MySQL、PostgreSQL、SQLite、SQL Server、ClickHouse 等自动迁移自动根…...

自动化立体仓库堆垛机控制系统STEP7 OB1功能块
1、堆垛机控制系统STEP7硬件组态如下图 CPU CPU 314C-2 PN/DP 6ES7 314-6EH04-0AB0 SM 338 POS-INPUT AO2x12Bit 6ES7 332-5HB01-0AB0 2、堆垛机控制系统STEP7内部变量 前进HMI M 0.0 BOOL 后退HMI M 0.1 BOOL 上升HMI M 0.2 B…...

MATLAB生成大规模无线通信网络拓扑(任意节点数量)
功能: 生成任意节点数量的网络拓扑,符合现实世界节点空间分布和连接规律 效果: 30节点: 100节点: 500节点: 程序: %创建时间:2025年6月8日 %zhouzhichao %自然生长出n节点的网络% …...

ubuntu 20.04挂载固态硬盘
我们有个工控机,其操作系统是ubuntu 20.04。可以接入一个固态硬盘。将固态硬盘插好后,就要进行挂载。在AI的指导下,过程并不顺利。记录如下: 1、检查硬盘是否被识别 安装好硬盘后,运行以下命令来检查Linux系统是否…...
【AI教我写网站-ECG datacenter】
阶段性总结:后端用户管理基础 在项目管理和协作中,清晰地阐述“为什么做”比“怎么做”更能凝聚共识和提供方向。我们不仅要理解技术实现,更要明白其背后的动机和意义。 让我们重新回顾并总结我们到目前为止的工作,这次会更侧重…...
2. Web网络基础 - 协议端口
深入解析协议端口与netstat命令:网络工程师的实战指南 在网络通信中,协议端口是服务访问的门户。本文将全面解析端口概念,并通过netstat命令实战演示如何监控网络连接状态。 一、协议端口核心知识解析 1. 端口号的本质与分类 端口范围类型说…...

PC与Windows远程连接与串流:方案简介(ZeroTier + Parsec、Moonlight + Sunshine、网易UU远程)
简介 在远程办公、云游戏、家用 NAS 串流、图形远程渲染等需求增长的背景下,越来越多用户开始寻找低延迟、高画质、跨网络可用的远程连接方案。今天这篇文章将深度分析三种目前在玩家圈和远程办公中都非常流行的组合方案: 🟢 ZeroTier Pars…...

SpringBoot+MySQL家政服务平台 设计开发
概述 基于SpringBootMySQL开发的家政服务平台完整项目,该系统实现了用户预约、服务管理、订单统计等核心功能,采用主流技术栈开发,代码规范且易于二次开发。 主要内容 系统功能架构 本系统采用前后端分离架构,前端提供用户交互…...

浏览器兼容-polyfill-本地服务-优化
babel和webpack结合 npx babel src --out-dir dist --presetsbabel/preset-env 这是把src下面的东西都用babel转化一下 webpack可以和babel结合使用,首先下载一个这东西: npm install babel-loader -D webpack配置: const path requir…...

c++ decltype关键字
decltype为类型推导关键字。 示例代码: // decltype也可用于函数模板编程: template<typename T, typename U> auto add(T t, U u) -> decltype(t u) {return t u; }// decltype推导函数返回类型 auto doubleNumFunc(int x) -> decltype(x * 2) {ret…...