nodejs 和 pm2 安装配置

Node.js 是一个 基于 Chrome V8 引擎的 JavaScript 运行环境,可以让 JavaScript 在服务器端运行

  • JavaScript : 原本只能在浏览器运行
  • Node.js : 让 JS 可以读写服务器

Node.js 的核心特点:

  • 单线程模型 ,通过 事件循环(Event Loop) 实现高并发。
  • 非阻塞 IO ,适合 IO 密集型任务,不适合 CPU 密集型任务(单线程一旦被卡住,整个服务器就会卡住)。
  • npm 生态npm 是世界最大的包管理平台。

Node.js 安装

wget https://nodejs.org/dist/latest/node-v15.12.0-linux-x64.tar.gz
tar -xf node-v15.12.0-linux-x64.tar.gz -C /usr/local
ln -s /usr/local/node-v15.12.0-linux-x64/bin/* /bin/

安装pm2

npm install pm2 -g
npm install -g [email protected] # 安装指定版本
npm install -g pm2@latest # 安装最新版本

Node.js 相关常见操作

安装包

npm install pm2

安装指定版本的包

npm install -g [email protected]

查看可用的安装版本

hexo 安装包为例,以下命令查看 hexo 安装包有哪些可选版本

# npm show hexo versions
[
'3.3.9', '3.4.0', '3.4.1', '3.4.2', '3.4.3',
'3.4.4', '3.5.0', '3.6.0', '3.7.0', '3.7.1',
'3.8.0', '3.9.0', '4.0.0', '4.1.0', '4.1.1',
'4.2.0', '4.2.1', '5.0.0', '5.0.1', '5.0.2',
'5.1.0', '5.1.1', '5.2.0', '5.3.0', '5.4.0',
'5.4.1', '5.4.2', '6.0.0', '6.1.0', '6.2.0',
'6.3.0', '7.0.0-rc1', '7.0.0-rc2'
]

查看已安装的包名

以下命令可显示安装的包及它们的版本

npm ls

如果要查看全局类型的包,使用 -g 选项

npm ls -g

卸载安装的包

npm uninstall package_name

卸载全局安装的包

npm uninstall package_name -g

Node.js 常见错误

WARN EACCES user “root” does not have permission to access the dev dir “/root/.node-gyp/11.15.0”
ERR! stack Error: EACCES: permission denied, mkdir ‘node_modules/sqlite3/.node-gyp’

[解决方法]:

npm install --unsafe-perm

Node.js 基础项目结构

一个 Node 项目通常是:

project
├─ node_modules
├─ package.json
├─ package-lock.json
├─ app.js
└─ routes

在 Node.js 生态中,通常有两个 核心基础配置文件

  • package.json : 这是每个 Node.js 项目的核心。它定义了项目的元数据、依赖项和运行脚本。
  • .env : 我们绝不应该把数据库密码、API 密钥等敏感信息直接写在代码里。通常配合 dotenv 库使用。

package.json 配置文件详解

{
"name": "admin",
"version": "4.4.0",
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
"author": "Auth <[email protected]>",
"main": "app.js",
"scripts": {
"dev": "vue-cli-service serve",
"build": "prisma generate && nest build",
"lint": "eslint --ext .js,.vue src",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"start": "nest start",
"preview": "node build/index.js --preview",
"new": "plop",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
"test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit"
},
"dependencies": {
"axios": "0.18.1",
"clipboard": "2.0.4"

},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.4",
"@vue/cli-plugin-eslint": "4.4.4",
"vue-template-compiler": "2.6.10"
},
"browserslist": [
"> 1%",
"last 2 versions"
],
"bugs": {
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
},
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"keywords": [
"vue",
"admin",
"dashboard",
"element-ui",
"management-system"
],
"license": "MIT",
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
}
}

  • name & version : 项目名称和版本。发布 npm 包时这是必填的唯一标识。
  • main : 程序主入口,Node 默认的执行文件。
  • scripts : 这是整个配置中最重要的部分。它定义了 快捷命令(命令脚本)
    • "start": "node app.js" -> 执行 npm start 命令,实际会运行 node app.js 启动程序。
    • "dev": "vue-cli-service serve" -> 执行 npm run dev 命令,会使用 vue-cli-service serve 启动服务
  • dependencies : 行环境必需的包(如 express, mongoose 等)。安装命令:npm install <pkg>
  • devDependencies : 仅开发环境需要的包(如 eslint, jest, nodemon )。安装命令:npm i <pkg> -D
  • engines : 指定 Node.js 或 npm 的版本范围,防止因环境版本不同导致代码崩溃。

初始化项目 ,会生成 package.json

npm init

安装依赖

npm install

启动

node app.js

PM2

如果直接使用 node app.js 这种方式启动,会存在以下问题:

  • 1️⃣ 程序崩溃自动退出,不会自动启动
  • 2️⃣ 服务器重启后,程序不会自动启动
  • 3️⃣ 无法负载均衡
  • 4️⃣ 日志不好管理

PM2 就是为解决这些问题而生,它是 Node.js 最流行的进程管理工具 。主要负责以下功能:

功能 说明
进程守护 程序崩溃自动重启
负载均衡 Node.js 是单线程的,pm2 可以让其充分利用多核 CPU 实现多进程
日志管理 自动手机程序日志
开机自启 服务器启动自动运行
性能监控 CPU/内存
后台运行 让程序以守护进程(Daemon)方式在后台运行

PM2 启动程序,假设程序是 app.js

pm2 start app.js --name "app-name"

查看进程状态

pm2 list

pm2 常用命令

  • 程序生命周期管理

    pm2 start app.js

    pm2 restart app-name|all|id

    pm2 stop app-name|all|id

    pm2 delete app

    pm2 reload <name> --update-env # PM2 会缓存环境变量。如果你修改了配置文件中的 env 变量,直接 pm2 restart 有时是不生效的。

    pm2 reload all # 平滑重启, 相比 restart,reload 会逐个重启进程,实现 0 秒停机
  • 查看进程

    pm2 list
  • 日志管理

    pm2 logs     # 默认日志位置 ~/.pm2/logs
    pm2 logs app-name

    pm2 flush # 清空日志

    pm2 set pm2-logrotate:max_size 10M # PM2 日志会越来越大。建议配置 日志轮转
  • 监控程序,查看 CPU/Memory 实时监控界面

    pm2 monit
  • 配置 pm2 开机自启动

    pm2 save      # 保存当前进程列表
    pm2 startup # 生成启动脚本命令,复制终端弹出的那行代码并执行。
    pm2 resurrect # 查看开机启动进程

PM2 集群模式

Node.js 是单线程 。PM2 可以启动 多进程利用多核 CPU

  • ✔ 提高性能

  • ✔ 提高并发

  • ✔ 程序挂掉自动拉起

  • 集群模式启动命令

    pm2 start app.js -i max
    • -i max : 根据 CPU 核心数启动,如 4 vCPU 则启动 4 个 node 进程。

PM2 配置文件

生产环境一般使用 ecosystem.config.js 作为 pm2 管理配置文件来管理所有的项目,让你的部署过程 版本化、自动化、可复用

ecosystem.config.js
module.exports = {
apps : [{
// --- 基础配置 ---
name: "myapp", // 应用名称,用于 pm2 list 展示
cwd: "./", // 应用运行的根目录
script: "app.js", // 启动脚本路径
args: "-- port 3000", // 传递给运行脚本的参数

// --- 进阶控制 ---
instances: "max", // 开启集群模式,利用多 CPU。数字或 "max"(根据 CPU 核心数启动)
exec_mode: "cluster", // 模式:'cluster'(集群)或 'fork'(单实例),默认为 'fork'
watch: false, // 监控目录,文件变动则自动重启,'false' 或者监控目标 '["node_modules", "logs"]'
ignore_watch: [ // 忽略监听目录,防止频繁重启。
"node_modules",
"logs"
],

// --- 日志管理 ---
error_file: "./logs/err.log", // 错误日志路径
out_file: "./logs/out.log", // 普通输出日志路径
log_date_format: "YYYY-MM-DD HH:mm:ss", // 给日志加上时间戳

// --- 环境变量控制 ---
env: { // 默认环境变量 (pm2 start)
NODE_ENV: "development"
},
env_production : { // 生产环境变量 (pm2 start --env production)
NODE_ENV: "production"
},

// --- 重启策略 ---
autorestart: true, // 程序崩溃是否自动重启
min_uptime: 60, // 程序运行多久才算启动成功
max_restarts: 10, // 最大重启次数,防止程序有问题还一直不停重启
max_memory_restart: "1G", // 内存占用超过 1G 则自动重启,防止内存泄漏
restart_delay: 3000 // 异常重启之间的延迟(毫秒)

}]
}
  • 启动命令
    pm2 start ecosystem.config.js

    pm2 start ecosystem.config.js --env production # 启动生产环境 env

使用 PM2 配置文件时,需要注意以下事项:

  • 集群模式(Cluster)与单实例(Fork)

    如果你的应用是单机版的,没做多进程适配(例如:在内存里存 Session、使用本地变量计数),开启 instances: max 会导致数据不一致。

    生产环境尽量使用 cluster 模式以压榨多核性能,但确保你的应用是 无状态(Stateless) 的。

  • 内存溢出防御

    • Node.js 程序如果不小心写了内存泄漏,长期运行会导致服务器宕机。
    • 务必配置 max_memory_restart 。比如你的服务器有 2G 内存,给每个实例设个 800M 左右的阈值,能有效防止全机卡死。
  • 避免 无限重启循环

    • 如果你的程序在启动阶段就报错,PM2 会疯狂尝试重启。
    • 设置 min_uptime (程序运行多久才算启动成功)和 max_restarts (最大重试次数),避免刷爆 CPU 和日志文件。
  • Watch 模式的风险

    • 不要在生产环境开启 watch: true
    • 生产环境下任何小的配置改动或日志写入(如果路径不对)都可能触发进程重启,导致服务抖动。 watch 仅建议在开发或测试环境使用。
  • 环境变量的优先级

    • PM2 会缓存环境变量。如果你修改了配置文件中的 env 变量,直接 pm2 restart 有时是不生效的。
    • 建议使用 pm2 reload <name> --update-env 或直接 pm2 delete 后再重新 start