docker-nodejs-files-folder-upload-pm2-example
这是一个 nodejs + express + html 实现的文件以及文件夹上传例子,构建部署使用的是 docker + pm2 + nginx 技术。
通过这个例子,你将会学习到以下技术点:
- 前端拖拽上传文件和文件夹(fetct api 上传)
- 前端读取文件夹中的文件数据
- 后端通过 nodejs + express + multer 处理前端传过来的数据并写入文件和文件夹
- 使用 docker + nginx 托管前端项目
- 使用 docker + nginx 反向代理
- 使用 docker + pm2 部署 nodejs 项目
- 使用 docker 和 docker compose 构建部署,以及一些常用的命令
源码
百度搜索 李钟意讲前端 gitee
https://gitee.com/fe521/docker-nodejs-files-folder-upload-pm2-example
环境
1. 安装环境
- vscode https://code.visualstudio.com/download
- nodejs https://nodejs.org/en/download
- docker https://www.docker.com/products/docker-desktop/
- 下载 Windows node.js v18.16.0 https://nodejs.org/dist/v18.16.0/node-v18.16.0-x64.msi
- 下载 Windows Docker desktop https://desktop.docker.com/win/main/amd64/Docker Desktop Installer.exe
2. 测试你的环境
node -v
npm -v
docker --version
docker compose version
启动项目
生产环境
构建部署
docker compose up --build -d
docker compose up
: 运行 Docker Compose 命令来启动并运行定义在docker-compose.yml
文件中的所有服务。--build
: 这个选项告诉 Docker Compose 在启动服务之前先构建(或重新构建)服务的镜像。这对于确保使用最新的代码和依赖项是非常有用的。-d
: 这个选项将容器置于后台运行(detached mode),即容器会在后台运行,不会占用命令行。
停止
docker compose down
- 这个命令会停止并移除由
docker-compose.yml
文件定义的所有容器。 - 此命令还会移除网络、卷和默认的网络驱动,除非有额外的参数指定保留它们。
docker compose down --rmi=all
docker compose down --rmi=local
这将停止和删除所有容器、网络、卷,并且删除所有关联的镜像。
all
:删除所有停止状态的容器所关联的镜像。这是删除所有镜像的选项,包括那些可能未被任何容器使用的镜像。local
:只删除本地创建的镜像,即那些没有标签或者标签为<none>
的镜像。
开发环境
- 切换到 backend 目录
cd backend
- 修改把注释移除 backend/index.js
app.use(express.static("../frontend"));
- 启动项目
npm start
- 浏览器访问
文件树
docker-nodejs-files-folder-upload-pm2-example
|
+---backend # 后端目录
| .npmrc # npm 配置文件,用于管理npm的行为和帮助处理包的安装
| Dockerfile # 用于构建后端服务的Docker容器的Dockerfile
| ecosystem.config.js # PM2进程管理器的配置文件,用于帮助管理和维护Node.js应用的运行
| index.js # 后端应用的主入口文件
| package.json # 包含项目依赖和其他配置的npm包文件
|
+---frontend # 前端目录
| index.html # 前端的主HTML文件,通常是应用的入口点
| .gitignore # Git配置文件,用于指定不需要加入版本控制的文件和目录
| docker-compose.yml # Docker Compose配置文件,用于定义和运行多容器Docker应用
| Dockerfile # 用于构建前端服务的Docker容器的Dockerfile
| nginx.conf # Nginx配置文件,通常用于配置Nginx服务器以服务于前端文件
| RADME.md # 项目的README文件,通常包含项目说明、安装步骤等信息(注意这里应该是“README.md”)
如何查看 docker pm2 的性能
这是我的 docker 容器
PS C:\Users\Administrator\Desktop\node-express> docker compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
node_express_nginx node-express-nginx "/docker-entrypoint.…" nginx 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp
node_express_server node-express-backend "docker-entrypoint.s…" backend 5 minutes ago Up 5 minutes 3000/tcp
PS C:\Users\Administrator\Desktop\node-express>
要查看使用 PM2 部署在 Docker 容器 node_express_server
中的应用性能,你可以按照以下步骤操作:
1. 进入容器:
首先,你需要进入运行你的 Node.js 应用的 Docker 容器。可以使用以下 Docker 命令:
docker exec -it node_express_server /bin/bash
注意,根据你的容器中安装的 shell 类型,可能需要使用 /bin/sh
替换 /bin/bash
。
2. 检查 PM2:
进入容器后,你可以使用 PM2 的命令来查看应用的性能和状态。如果 PM2 已经在容器中运行,你可以使用:
pm2 status
这个命令会显示所有由 PM2 管理的进程的状态,包括 CPU 和内存的使用情况。
3. 查看更详细的指标:
如果你需要更详细的性能指标,可以使用 PM2 的 Monitoring 功能。运行:
pm2 monit
这个命令提供了一个实时的监控界面,显示 CPU 使用率、内存使用情况等详细信息。
4. 日志信息:
查看应用日志也是分析性能问题的一个好方法。使用以下命令可以查看应用日志:
pm2 logs
5. 退出容器:
完成检查后,你可以输入 exit
来离开 Docker 容器。
确保你的 Docker 容器中已经安装了 PM2。如果没有安装,你可以通过运行 npm install pm2 -g
来全局安装 PM2。
Process List 是啥意思为啥有 32 个一样的
在你提供的 pm2 status
输出中,"Process List" 部分显示了你的应用的所有实例(或称为进程)。这里你看到的有多个一样的条目,表示你的应用在运行多个实例。
这种情况通常出现在以下几个方面:
1. Cluster Mode:
你的应用在 PM2 的集群模式下运行。集群模式允许一个 Node.js 应用利用多核 CPU 的优势,通过启动多个实例来提高性能和可用性。每个实例都是应用的一个独立副本,运行在自己的进程中。
2. 多实例提升性能:
通过运行多个实例,你的应用可以更有效地处理并发请求,因为每个实例都可以独立处理一部分请求。这有助于减少延迟和增加吞吐量。
3. 负载均衡:
PM2 会自动处理这些实例之间的负载均衡,确保请求均匀分配到每个实例上。
你看到的每个实例都有相同的应用名称和配置,但它们的 pid
(进程标识符)是不同的。这表明它们是相同应用的不同副本。在你的例子中,有 27 个实例运行,这可能是基于你服务器的 CPU 核心数或者你在 PM2 配置文件中指定的实例数。
检查实例数的原因
如果你想了解为什么启动了这么多实例,可以检查你的 PM2 配置文件(通常是一个名为 ecosystem.config.js
的文件)。
在这个文件中,你可以找到关于应用部署的详细配置,包括启动的实例数。例如:
module.exports = {
apps: [
{
script: "app.js",
instances: "max",
exec_mode: "cluster",
},
],
};
在这个例子中,instances: 'max'
表示将根据可用的 CPU 核心数最大化实例数量。如果想要改变实例数,你可以在这里修改这个数值。
了解应用如何运行和被 PM2 管理是非常重要的,这有助于你更好地监控和优化应用性能。如果你发现这些实例数过多或不必要,你可以调整配置以更好地适应你的需求。
它是怎么算的,我如何通过 powershell 查看 cpu 的核心数以及 pm2 使用的核心数
在 PowerShell 中查看 CPU 的核心数和通过 PM2 管理的应用所使用的核心数有一些简单的方法。首先,我们来看如何获取系统的 CPU 核心数,然后我会解释如何检查 PM2 配置来确定使用了多少核心。
1. 查看系统的 CPU 核心数
在 PowerShell 中,你可以使用以下命令来查看 CPU 的总核心数:
Get-WmiObject -Class Win32_Processor | Select-Object -Property NumberOfCores, NumberOfLogicalProcessors
这条命令会显示每个处理器的核心数 (NumberOfCores
) 和逻辑处理器数 (NumberOfLogicalProcessors
)。逻辑处理器数通常是物理核心数的两倍,如果启用了超线程技术。
2. 查看 PM2 使用的核心数
对于 PM2,核心数的使用取决于你的 PM2 配置文件(通常是 ecosystem.config.js
)。要查看 PM2 配置,你需要查找配置文件中关于 instances
的设置。通常,你可以通过查看你的应用目录中的 PM2 配置文件来得到这些信息。
如果你不确定配置文件的位置,可以先通过 cd
命令进入你的应用目录,然后使用以下命令查找所有 JS 文件:
Get-ChildItem -Recurse -Filter *.js
在找到 ecosystem.config.js
文件后,你可以使用 Get-Content
命令查看它的内容:
Get-Content ecosystem.config.js
在这个配置文件中,查找如下配置项:
instances: "max"; // 或者是一个具体的数字
- 如果设置为
'max'
,PM2 会尽可能使用所有可用的逻辑处理器。 - 如果是数字,比如
4
,那就表示 PM2 配置了 4 个实例。
结合 PowerShell 和 PM2
你也可以结合使用 PowerShell 命令和查看 PM2 的日志或状态来动态地获取使用情况。例如,你可以直接在容器或系统内运行 pm2 show <app_name>
或 pm2 status
来获取当前运行的实例数。
这是我的 powershell cpu
PS C:\Users\Administrator\Desktop\node-express> Get-WmiObject -Class Win32_Processor | Select-Object -Property NumberOfCores, NumberOfLogicalProcessors
NumberOfCores NumberOfLogicalProcessors
------------- -------------------------
24 32
PS C:\Users\Administrator\Desktop\node-express>
从你提供的 PowerShell 命令输出中可以看到,你的系统有 24 个物理核心和 32 个逻辑处理器。逻辑处理器的数量比物理核心多,这通常意味着你的 CPU 支持超线程技术(Hyper-Threading),每个核心可以同时处理两个线程。
如何理解这些数据:
- 物理核心(NumberOfCores):这是物理上存在的核心数,每个核心是一个独立的处理单元。
- 逻辑处理器(NumberOfLogicalProcessors):逻辑处理器或线程是操作系统可以利用的处理单元数。在支持超线程的系统中,每个物理核心可以被视为两个逻辑处理器。
关于 PM2 使用的核心数:
根据你之前提供的 PM2 status
信息,你的应用以集群模式运行,启动了多个实例。如果你在 PM2 配置中设置了 instances
为 'max'
,PM2 会尽可能利用所有可用的逻辑处理器,即 32 个。如果你看到的实例数量接近或等于这个数字,这可能就是配置的结果。
操作建议:
- 配置调整:如果你觉得应用的实例数过多或者想更精确地控制负载分配,可以考虑调整 PM2 的
instances
设置。例如,你可以设置一个小于 32 的数字,来限制使用的逻辑处理器数量。 - 性能监控:继续监控应用的性能,特别是在高负载情况下。观察 CPU 和内存使用情况,确保没有资源过载或浪费。
如果你需要进一步帮助来调整或优化你的 PM2 配置,或者对如何更好地利用你的服务器资源有疑问,可以随时向我咨询。
pm2 status
PS C:\Users\Administrator\Desktop\node-express> docker exec -it node_express_server /bin/bash
root@ca234dc7296e:/app# pm2 status
┌────┬─────────────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼─────────────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ node-express-backend │ default │ 1.0.0 │ cluster │ 18 │ 13m │ 0 │ online │ 0% │ 59.0mb │ root │ disabled │
│ 1 │ node-express-backend │ default │ 1.0.0 │ cluster │ 25 │ 13m │ 0 │ online │ 0% │ 60.7mb │ root │ disabled │
│ 2 │ node-express-backend │ default │ 1.0.0 │ cluster │ 32 │ 13m │ 0 │ online │ 0% │ 58.7mb │ root │ disabled │
│ 3 │ node-express-backend │ default │ 1.0.0 │ cluster │ 39 │ 13m │ 0 │ online │ 0% │ 57.4mb │ root │ disabled │
│ 4 │ node-express-backend │ default │ 1.0.0 │ cluster │ 50 │ 13m │ 0 │ online │ 0% │ 59.5mb │ root │ disabled │
│ 5 │ node-express-backend │ default │ 1.0.0 │ cluster │ 61 │ 13m │ 0 │ online │ 0% │ 59.7mb │ root │ disabled │
│ 6 │ node-express-backend │ default │ 1.0.0 │ cluster │ 72 │ 13m │ 0 │ online │ 0% │ 59.4mb │ root │ disabled │
│ 7 │ node-express-backend │ default │ 1.0.0 │ cluster │ 83 │ 13m │ 0 │ online │ 0% │ 62.3mb │ root │ disabled │
│ 8 │ node-express-backend │ default │ 1.0.0 │ cluster │ 94 │ 13m │ 0 │ online │ 0% │ 59.0mb │ root │ disabled │
│ 9 │ node-express-backend │ default │ 1.0.0 │ cluster │ 101 │ 13m │ 0 │ online │ 0% │ 59.3mb │ root │ disabled │
│ 10 │ node-express-backend │ default │ 1.0.0 │ cluster │ 116 │ 13m │ 0 │ online │ 0% │ 59.6mb │ root │ disabled │
│ 11 │ node-express-backend │ default │ 1.0.0 │ cluster │ 127 │ 13m │ 0 │ online │ 0% │ 61.3mb │ root │ disabled │
│ 12 │ node-express-backend │ default │ 1.0.0 │ cluster │ 138 │ 13m │ 0 │ online │ 0% │ 58.9mb │ root │ disabled │
│ 13 │ node-express-backend │ default │ 1.0.0 │ cluster │ 149 │ 13m │ 0 │ online │ 0% │ 59.8mb │ root │ disabled │
│ 14 │ node-express-backend │ default │ 1.0.0 │ cluster │ 160 │ 13m │ 0 │ online │ 0% │ 61.8mb │ root │ disabled │
│ 15 │ node-express-backend │ default │ 1.0.0 │ cluster │ 171 │ 13m │ 0 │ online │ 0% │ 60.0mb │ root │ disabled │
│ 16 │ node-express-backend │ default │ 1.0.0 │ cluster │ 182 │ 13m │ 0 │ online │ 0% │ 59.0mb │ root │ disabled │
│ 17 │ node-express-backend │ default │ 1.0.0 │ cluster │ 193 │ 13m │ 0 │ online │ 0% │ 59.7mb │ root │ disabled │
│ 18 │ node-express-backend │ default │ 1.0.0 │ cluster │ 204 │ 13m │ 0 │ online │ 0% │ 60.2mb │ root │ disabled │
│ 19 │ node-express-backend │ default │ 1.0.0 │ cluster │ 215 │ 13m │ 0 │ online │ 0% │ 59.7mb │ root │ disabled │
│ 20 │ node-express-backend │ default │ 1.0.0 │ cluster │ 226 │ 13m │ 0 │ online │ 0% │ 59.5mb │ root │ disabled │
│ 21 │ node-express-backend │ default │ 1.0.0 │ cluster │ 237 │ 13m │ 0 │ online │ 0% │ 59.3mb │ root │ disabled │
│ 22 │ node-express-backend │ default │ 1.0.0 │ cluster │ 248 │ 13m │ 0 │ online │ 0% │ 59.2mb │ root │ disabled │
│ 23 │ node-express-backend │ default │ 1.0.0 │ cluster │ 259 │ 13m │ 0 │ online │ 0% │ 59.9mb │ root │ disabled │
│ 24 │ node-express-backend │ default │ 1.0.0 │ cluster │ 270 │ 13m │ 0 │ online │ 0% │ 59.3mb │ root │ disabled │
│ 25 │ node-express-backend │ default │ 1.0.0 │ cluster │ 281 │ 13m │ 0 │ online │ 0% │ 60.0mb │ root │ disabled │
│ 26 │ node-express-backend │ default │ 1.0.0 │ cluster │ 292 │ 13m │ 0 │ online │ 0% │ 59.6mb │ root │ disabled │
│ 27 │ node-express-backend │ default │ 1.0.0 │ cluster │ 303 │ 13m │ 0 │ online │ 0% │ 58.9mb │ root │ disabled │
│ 28 │ node-express-backend │ default │ 1.0.0 │ cluster │ 314 │ 13m │ 0 │ online │ 0% │ 60.0mb │ root │ disabled │
│ 29 │ node-express-backend │ default │ 1.0.0 │ cluster │ 325 │ 13m │ 0 │ online │ 0% │ 59.4mb │ root │ disabled │
│ 30 │ node-express-backend │ default │ 1.0.0 │ cluster │ 336 │ 13m │ 0 │ online │ 0% │ 59.0mb │ root │ disabled │
│ 31 │ node-express-backend │ default │ 1.0.0 │ cluster │ 347 │ 13m │ 0 │ online │ 0% │ 58.5mb │ root │ disabled │
└────┴─────────────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
root@ca234dc7296e:/app#
这是一个显示 Docker 容器内运行的 PM2 管理的 Node.js 应用程序状态的输出。PM2 是一个流行的 Node.js 应用程序的进程管理工具,常用于管理生产环境中的 Node.js 应用程序。这个特定的输出显示了使用 PM2 管理的名为 node-express-backend
的 Node.js 应用程序的多个实例的状态。
以下是输出中每一列的含义:
- id:实例的唯一标识符。
- name:进程的名称,这里是
node-express-backend
。 - namespace:命名空间,默认为
default
。 - version:应用程序的版本,这里是
1.0.0
。 - mode:运行模式,这里显示为
cluster
,表示应用程序是在集群模式下运行的,即多个实例同时运行以提高性能和可用性。 - pid:进程 ID。
- uptime:进程已运行的时间,这里各实例均为
13m
,即 13 分钟。 - ↺(重启次数):进程自上次启动以来的重启次数,这里为
0
,表示没有重启过。 - status:进程的当前状态,这里为
online
,表示进程正在运行中。 - cpu:进程当前占用的 CPU 百分比,这里均为
0%
。 - mem:进程当前占用的内存量,单位为 MB。
- user:运行该进程的用户,这里是
root
。 - watching:是否启用了文件监控,这里为
disabled
,表示没有启用。
此输出显示,你的 node-express-backend
应用的 32 个实例都在正常运行中,没有异常的资源使用或重启行为,运行状况良好。
pm2 monit
PS C:\Users\Administrator\Desktop\node-express> docker exec -it node_express_server /bin/bash
root@ca234dc7296e:/app# pm2 monit
┌─ Process List ───────────────────────────────────────┐┌── node-express-backend Logs ──────────────────────────────────────────────────────────────────────────────────────────────────┐
│[ 0] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[ 1] node-express-backend Mem: 60 MB CPU: 0 ││ │
│[ 2] node-express-backend Mem: 58 MB CPU: 0 ││ │
│[ 3] node-express-backend Mem: 58 MB CPU: 0 ││ │
│[ 4] node-express-backend Mem: 60 MB CPU: 1 ││ │
│[ 5] node-express-backend Mem: 61 MB CPU: 0 ││ │
│[ 6] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[ 7] node-express-backend Mem: 61 MB CPU: 0 ││ │
│[ 8] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[ 9] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[10] node-express-backend Mem: 58 MB CPU: 0 ││ │
│[11] node-express-backend Mem: 61 MB CPU: 0 ││ │
│[12] node-express-backend Mem: 59 MB CPU: 1 ││ │
│[13] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[14] node-express-backend Mem: 61 MB CPU: 0 ││ │
│[15] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[16] node-express-backend Mem: 58 MB CPU: 0 ││ │
│[17] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[18] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[19] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[20] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[21] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[22] node-express-backend Mem: 59 MB CPU: 1 ││ │
│[23] node-express-backend Mem: 60 MB CPU: 1 ││ │
│[24] node-express-backend Mem: 58 MB CPU: 0 ││ │
│[25] node-express-backend Mem: 60 MB CPU: 0 ││ │
│[26] node-express-backend Mem: 60 MB CPU: 0 ││ │
│[27] node-express-backend Mem: 59 MB CPU: 1 ││ │
│[28] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[29] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[30] node-express-backend Mem: 59 MB CPU: 0 ││ │
│[31] node-express-backend Mem: 58 MB CPU: 0 ││ │
└──────────────────────────────────────────────────────┘└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌─ Custom Metrics ─────────────────────────────────────┐┌─ Metadata ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Used Heap Size 11.18 MiB ││ App Name node-express-backend │
│ Heap Usage 88.7 % ││ Namespace default │
│ Heap Size 12.60 MiB ││ Version 1.0.0 │
│ Event Loop Latency p95 1.08 ms ││ Restarts 0 │
│ Event Loop Latency 0.30 ms ││ Uptime 20m │
│ Active handles 3 ││ Script path /app/index.js │
│ Active requests 0 ││ Script args N/A │
│ ││ Interpreter node │
│ ││ Interpreter args N/A │
│ ││ Exec mode cluster │
└──────────────────────────────────────────────────────┘└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
left/right: switch boards | up/down/mouse: scroll | Ctrl-C: exit To go further check out https://pm2.io/
这是在 Docker 容器中使用 pm2 monit
命令的输出,该命令提供了一个实时监控界面,用于监控通过 PM2 管理的 Node.js 应用程序的性能和运行状况。pm2 monit
显示了关于每个 Node.js 进程的内存和 CPU 使用情况、日志、自定义指标和元数据的详细信息。
下面是各部分的详细解释:
左侧:进程列表
- 进程列表:显示了每个由 PM2 管理的进程的内存和 CPU 使用率。例如,
[0] node-express-backend Mem: 59 MB CPU: 0%
表示进程编号为 0 的实例使用了大约 59 MB 的内存,CPU 使用率为 0%。
右上角:应用程序日志
- node-express-backend Logs:显示应用程序的日志输出。在这个面板中,日志内容为空,这可能是因为目前没有生成日志信息或者日志级别设置导致不显示日志。
左下角:自定义指标
- 自定义指标:显示了与 Node.js 应用程序性能相关的一些关键指标,如堆内存使用情况、事件循环延迟等。例如,
Used Heap Size 11.50 MiB
和Heap Usage 91.26%
分别显示了当前使用的堆大小和堆使用率。
右下角:元数据
- 元数据:提供了关于应用程序的基本信息,包括名称、命名空间、版本、重启次数、运行时间、脚本路径等。例如,
App Name node-express-backend
和Uptime 16m
分别显示了应用的名称和已运行时间。
操作提示
- 屏幕底部的提示如
left/right: switch boards | up/down/mouse: scroll | Ctrl-C: exit
提供了如何在pm2 monit
工具中导航的指南。
这个监控界面主要用于运维人员实时监控和分析应用程序的状态,帮助快速定位和解决可能出现的性能问题或异常。