Node + Express 后台开发 —— 上传、下载和发布 - 彭加李
source link: https://www.cnblogs.com/pengjiali/p/17385971.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
上传、下载和发布
前面我们已经完成了数据库的增删改查
,在弄一个上传
图片、下载
csv,一个最简单的后台开发就已完成,最后部署
即可。
需求
:做一个个人简介
的表单提交,有昵称
、简介
和头像
。后端能接收数据并保存到数据库。
接收不到数据
用 amis-editor
(amis 低代码编辑器,更多了解请看这里)绘制一个如下界面:
前端上传文件使用 InputFile
的手动上传。配置如下:
{
"type": "input-file",
"name": "file",
"label": "File",
"accept": "*",
"asBlob": true
}
后端定义一个路由:
// 个人简介
// http://localhost:3000/users/upload
router.post('/upload', function(req, res, next) {
console.log('req', req.body)
res.send({"status":0,"msg":"","data":{}});
});
输入信息后提交,后端 req.body
是空对象,说明无法接收数据:
req {}
POST /users/upload 200 6.230 ms - 31
前端传输数据如下:
如果前端不传文件
,后端 req.body 则能正常接收数据:
req { nickname: 'pjl', introduction: 'i am pjl', file: '' }
POST /users/upload 200 26.287 ms - 31
Tip:Content-Type 用于指示资源的 MIMIE 类型,请求中,客户端告诉服务器实际发送的数据类型。相应中,告诉客户端发送的内容的内容类型。不传文件请求头的 Content-Type 是 Content-Type: application/json
;传了文件,请求头的 Content-Type 是 Content-Type: multipart/form-data; boundary=----
。需要在表单中进行文件上传时,就需要使用该格式:multipart/form-data
。
multer
Multer 是一个 node.js 中间件,用于处理 multipart/form-data
类型的表单数据,它主要用于上传文件。
注:Multer 不会处理任何非 multipart/form-data 类型的表单数据
安装 multer
:
PS E:\pjl-back-end> npm install --save multer
added 17 packages, and audited 119 packages in 18s
3 packages are looking for funding
run `npm fund` for details
4 vulnerabilities (3 high, 1 critical)
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
使用 multer:
PS E:\pjl-back-end> git diff routes/users.js
+const multer = require('multer')
+// 启动服务后,自动在 public 下创建 uploads 文件夹
+const upload = multer({ dest: 'public/uploads/' })
+// 一旦请求过来,就会先经过中间件把接收到的图片存入 uploads 文件夹中,然后在到下一步
+// file 是前端文件的 name。由于这里是一张图片,所以用 single 方法。多张图片的使用请看文档
+router.post('/upload', upload.single('file'), function(req, res, next) {
+ // req.body 将具有文本域数据,如果存在的话
+ console.log(req.body)
+ // req.file 是 `file` 文件的信息
+ console.log(req.file)
res.send({"status":0,"msg":"","data":{}});
});
启动服务后,会自动
在 public 下创建 uploads
文件夹。输入昵称、简介和头像,点击提交。头像文件会重命名并上传到 uploads 中,通过 req.body
可以取得昵称和简介,通过 req.file
可以取得文件信息。后续存入数据库的操作笔者就不在进行,无非就是通过 token 取得用户 id,然后将昵称、简介和头像路径传给 services,通过 model 保存到数据库。
Tip:虽然文件没有了后缀(.png),通过chrome 直接访问图片路径(http://localhost:3000/uploads/36d8bda3160d8d09e81b167de1969b47
)会自动下载,把图片路径给到 image 是可以正常使用。
下载csv
需求
:点击导出全部
按钮,发起请求,通过后端直接下载 csv 文件,里面是表格数据。
安装 json2csv
包,用于将数据库中查询的 json 转为 csv:
PS E:\pjl-back-end> npm install json2csv
added 4 packages, and audited 123 packages in 4s
3 packages are looking for funding
run `npm fund` for details
4 vulnerabilities (3 high, 1 critical)
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
PS E:\pjl-back-end>
安装 iconv-lite
用于编码转换:
PS E:\pjl-back-end> npm i iconv-lite
added 2 packages, changed 1 package, and audited 125 packages in 3s
3 packages are looking for funding
run `npm fund` for details
4 vulnerabilities (3 high, 1 critical)
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
新建 utils.js,导出 downloadResource
方法用于下载 csv:
// E:\pjl-back-end\libs\utils.js
const Parser = require('json2csv').Parser;
const downloadResource = (res, fileName, fields, data) => {
const json2csv = new Parser({ fields });
const csv = json2csv.parse(data);
// iconv-lite: Pure JS character encoding conversion 转码,防止中文乱码
const iconv = require('iconv-lite');
const newCsv = iconv.encode(csv, 'gbk')
res.header('Content-Type', 'text/csv');
res.attachment(fileName);
return res.send(newCsv);
}
module.exports = {
downloadResource,
}
在任意路由中增加下载的处理请求:
const downloadResource = require('../libs/utils').downloadResource;
router.get('/download', function(req, res, next) {
// 列名
const fields = [
{
label: '姓名',
value: 'name'
},
{
label: '年龄',
value: 'age'
},
];
// 模拟从数据库查询出的数据
const data = [
{ "name":"peng 彭", "age": 18},
{ "name":"jia 加", "age": 19},
{ "name":"li 李", "age": 20},
{ "name":"pjl 彭加李", "age": 21},
];
return downloadResource(res, 'users.csv', fields, data);
});
重启服务,浏览器输入 localhost:3000/users/download
回车后会自动下载 csv 文件。双击打开 csv,效果如下:
如果不转码处理,这里 csv 中的中文就会乱码。
疑惑
:网上说 gbk和utf8都是都能编码中英文。将 gbk 改为 utf8
,在 win7 中打开 csv 仍旧乱码,或许是win7 中打开csv是gbk,得保持客户端和服务器编码一致?
假如 node 项目已经开发完毕,得将应用部署到服务器中。
直接使用 node app.js
一旦关闭终端,服务就会中断
虽然也可以使用 node app.js &
后台启动服务,但也有很多不足,比如重新发布代码不会自动生效
Tip: windows 下关闭后台启动的服务,比如端口是 3000
PS E:\pjl-back-end> netstat -ano|findstr 3000
TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 12384
TCP [::]:3000 [::]:0 LISTENING 12384
TCP [::1]:3000 [::1]:10229 TIME_WAIT 0
TCP [::1]:10230 [::1]:3000 TIME_WAIT 0
PS E:\pjl-back-end> taskkill /PID 12384 /F
成功: 已终止 PID 为 12384 的进程。
nodemon app.js
常用于开发环境
笔者这里使用 pm2。有如下好处:
- 监控服务资源
- 发布代码、宕机后会自动重启
- 比如你的是cpu 是4核,也能充分利用
- 能查看日志
体验 pm2
全局安装 pm2
PS E:\pjl-back-end> npm install pm2 -g
npm WARN deprecated [email protected]: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
added 184 packages, and audited 185 packages in 25s
12 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
PS E:\pjl-back-end> pm2 list
下面我们使用 pm2 启动服务:
Tip: 笔者由于环境问题,使用 npx 运行 pm2。你们可以省略。
通过 pm2 --version
查看版本,说明安装成功:
PS E:\pjl-back-end> npx pm2 --version
5.3.0
通过 pm2 start 入口文件
启动服务:
PS E:\pjl-back-end> npx pm2 start ./bin/www
[PM2] Starting E:\pjl-back-end\bin\www in fork_mode (1 instance)
[PM2] Done.
┌────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──
────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──
────────┼──────────┤
│ 0 │ www │ default │ 0.0.0 │ fork │ 9904 │ 0s │ 0 │ online │ 0% │ 42.0mb │ Adm… │ disabled │
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──
────────┴──────────┘
应用的 id
是 0,name
是 www,后续删除、启动和重启应用使用 id 和 name 都可以。
↺
表示重启次数为0。后续重启应用会自动增加。
status 中的 online
表示已上线。
通过 pm2 list
显示应用列表,比如目前有一个服务(www
)已启动(online
):
PS E:\pjl-back-end> npx pm2 list
┌────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──
────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──
────────┼──────────┤
│ 0 │ www │ default │ 0.0.0 │ fork │ 9904 │ 2m │ 0 │ online │ 0% │ 57.9mb │ Adm… │ disabled │
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──
────────┴──────────┘
通过 pm2 restart id|name
重启服务:
// 通过 id 重启
PS E:\pjl-back-end> npx pm2 restart 0
Use --update-env to update environment variables
[PM2] Applying action restartProcessId on app [0](ids: [ '0' ])
[PM2] [www](0) ✓
┌────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──
────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──
────────┼──────────┤
│ 0 │ www │ default │ 0.0.0 │ fork │ 12088 │ 0s │ 1 │ online │ 0% │ 41.9mb │ Adm… │ disabled │
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──
────────┴──────────┘
// 通过 name 重启
PS E:\pjl-back-end> npx pm2 restart www
Use --update-env to update environment variables
[PM2] Applying action restartProcessId on app [www](ids: [ 0 ])
[PM2] [www](0) ✓
┌────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──
────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──
────────┼──────────┤
│ 0 │ www │ default │ 0.0.0 │ fork │ 6648 │ 0s │ 2 │ online │ 0% │ 40.9mb │ Adm… │ disabled │
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──
Tip: ↺
表示重启过几次了
pm2 info www
查看 www 这个应用的详细信息:
PS E:\pjl-back-end> npx pm2 info www
Describing process with id 0 - name www
┌───────────────────┬────────────────────────────────────────────────┐
│ status │ online │
│ name │ www │
│ namespace │ default │
│ version │ 0.0.0 │
│ restarts │ 2 │
│ uptime │ 62s │
│ script path │ E:\pjl-back-end\bin\www │
│ script args │ N/A │
│ error log path │ C:\Users\Administrator\.pm2\logs\www-error.log │
│ out log path │ C:\Users\Administrator\.pm2\logs\www-out.log │
│ pid path │ C:\Users\Administrator\.pm2\pids\www-0.pid │
│ interpreter │ node │
│ interpreter args │ N/A │
│ script id │ 0 │
│ exec cwd │ E:\pjl-back-end │
│ exec mode │ fork_mode │
│ node.js version │ 16.20.0 │
│ node env │ N/A │
│ watch & reload │ ✘ │
│ unstable restarts │ 0 │
│ created at │ 2023-05-09T07:28:11.550Z │
└───────────────────┴────────────────────────────────────────────────┘
Revision control metadata
┌──────────────────┬──────────────────────────────────────────┐
│ revision control │ git │
│ remote url │ N/A │
│ repository root │ E:\pjl-back-end │
│ last update │ 2023-05-09T07:28:12.179Z │
│ revision │ a02f7d6427fde5fdce41aff1626d31c19d80fcdf │
│ comment │ 取消数据库和登录标识 │
│ branch │ master │
└──────────────────┴──────────────────────────────────────────┘
Actions available
┌────────────────────────┐
│ km:heapdump │
│ km:cpu:profiling:start │
│ km:cpu:profiling:stop │
│ km:heap:sampling:start │
│ km:heap:sampling:stop │
└────────────────────────┘
Trigger via: pm2 trigger www <action_name>
Code metrics value
┌────────────────────────┬───────────┐
│ Used Heap Size │ 20.15 MiB │
│ Heap Usage │ 89 % │
│ Heap Size │ 22.64 MiB │
│ Event Loop Latency p95 │ 2.04 ms │
│ Event Loop Latency │ 0.08 ms │
│ Active handles │ 4 │
│ Active requests │ 0 │
└────────────────────────┴───────────┘
Divergent env variables from local env
Add your own code metrics: http://bit.ly/code-metrics
Use `pm2 logs www [--lines 1000]` to display logs
Use `pm2 env 0` to display environment variables
Use `pm2 monit` to monitor CPU and Memory usage www
通过 pm2 monit id|name
监控应用程序:
PS E:\pjl-back-end> npx pm2 monit www
┌─ Process List ───────────────────────── ─ www Logs ─────────────────┐┌─ Logs ───────────────────────────────────────────────
[ 0] www Mem: 59 MB CPU: 0 % online │www > 错误信息
│ │www > GET /users/testlog 304 1.186 ms - -
│ │www > 信息
│ │www > 错误信息
│ │www > GET /users/testlog 304 1.837 ms - -
│ │www > 信息
│ │www > GET /users/testlog 304 0.914 ms - -
│ │www > 错误信息
│ │www > 信息
│ │www > 错误信息
│ │www > GET /users/testlog 304 1.369 ms - -
│ │www > 信息
│ │www > 错误信息
│ │www > GET /users/testlog 304 1.733 ms - -
│ │www > 信息
│ │www > 错误信息
│ │www > GET /users/testlog 304 3.095 ms - -
└─────────────────────────────────────────────────────────────────┘└────────────────────────────────────────────
┌─ Custom Metrics ────────────────────────────────────────────────┐┌─ Metadata ──────────────────────────────────────────────
│Used Heap Size 20.94 MiB │App Name www
│Heap Usage 91.45 % │Namespace default
│Heap Size 22.89 MiB │Version 0.0.0
│Event Loop Latency p95 9.12 ms │Restarts 2
│Event Loop Latency 0.14 ms │Uptime 2m
└─────────────────────────────────────────────────────────────────┘└────────────────────────────────────────────
left/right: switch boards | up/down/mouse: scroll | Ctrl-C: exit To go further check out https://pm2.io/
Tip:日志信息也会同步输出,日志就是console.log 或 console.error输出的内容,下文配置 pm2
会讲到。
通过 pm2 stop id|name
停止服务:
PS E:\pjl-back-end> npx pm2 stop www
[PM2] Applying action stopProcessId on app [www](ids: [ 0 ])
[PM2] [www](0) ✓
┌────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──
────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──
────────┼──────────┤
│ 0 │ www │ default │ 0.0.0 │ fork │ 0 │ 0 │ 2 │ stopped │ 0% │ 0b │ Adm… │ disabled │
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──
────────┴──────────┘
关闭并删除应用
通过 pm2 delete id|name
关闭并删除应用:
PS E:\pjl-back-end> npx pm2 delete www
[PM2] Applying action deleteProcessId on app [www](ids: [ 0 ])
[PM2] [www](0) ✓
┌────┬───────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────
┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
└────┴───────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────
┴──────────┴──────────┘
稳定的服务
比如笔者写一个如下服务 app2.js:
// app2.js
const http = require('http')
const fs = require('fs')
const server = http.createServer()
const requestListener = (req, res) => {
const url = req.url
// 如果url是 '/',则返回主页
if(url === '/'){
res.end("home page")
}else if(url === '/b'){
res.end("page b")
}else if(url === '/error'){
throw new Error('故意报错')
}
}
server.on('request', requestListener)
server.listen('3000', () => {
console.log('服务器已启动')
})
通过 node app2.js
启动服务后,访问 localhost:3000/error
故意报错,服务就会死掉,无法在响应其他请求:
PS E:\pjl-back-end> node app2.js
服务器已启动
E:\pjl-back-end\app2.js:13
throw new Error('故意报错')
^
Error: 故意报错
at Server.requestListener (E:\pjl-back-end\app2.js:13:15)
at Server.emit (node:events:513:28)
at parserOnIncoming (node:_http_server:998:12)
at HTTPParser.parserOnHeadersComplete (node:_http_common:128:17)
如果改用 pm2
启动服务:
PS E:\pjl-back-end> npx pm2 start app2.js
[PM2] Starting E:\pjl-back-end\app2.js in fork_mode (1 instance)
[PM2] Done.
┌────┬─────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬─
─────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼─────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼─
─────────┼──────────┤
│ 0 │ app2 │ default │ 0.0.0 │ fork │ 12248 │ 0s │ 0 │ online │ 0% │ 40.2mb │ Adm… │ disabled │
└────┴─────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴─
─────────┴──────────┘
再次访问 localhost:3000/error
,通过 pm2 list
发现重启(↺
)次数从0变成了3,总之是重启了:
PS E:\pjl-back-end> npx pm2 list
┌────┬─────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬─
─────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼─────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼─
─────────┼──────────┤
│ 0 │ app2 │ default │ 0.0.0 │ fork │ 12196 │ 25s │ 3 │ online │ 0% │ 39.7mb │ Adm… │ disabled │
└────┴─────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴─
访问 http://localhost:3000/
页面显示 home page
,说明服务正常,也较之前更稳定。
配置 pm2
需求
:配置应用名称
、入口文件
、监控
、日志
、实例数
项目根目录新建 pm2 配置文件 pm2.config.json
:
{
"apps": {
// 应用名称
"name": "spug-back-end",
// 入口文件
"script": "./bin/www",
// 监控。修改代码后自动生效
"watch": true,
// 排除某些文件的监控
"ignore_watch": [
"node_modules",
"logs"
],
// 错误日志。通过 console.error() 输出
"error_file": "logs/error.log",
// 自定义日志。通过 console.log() 输出
"out_file": "logs/custom.log",
// 给日志添加时间。否则你得这么写 console.log('信息...', '2023-05-09 16:25:00')
// YYYY不要小写
"log_date_format": "YYYY-MM-DD HH:mm:ss",
// cpu 核数。不要超过服务器的 cpu 核数
// 笔者 cpu 核数是 2,这样会启动 2 个服务,能更好的利用服务器资源。
"instances": 2
}
}
Tip:windows 查看 CPU 核数 - 在 cmd 命令中输入 wmic
,然后在出现的新窗口中输入 cpu get NumberOfCores
:
PS E:\pjl-back-end> wmic
wmic:root\cli>cpu get NumberOfCores
NumberOfCores
2
修改 package.json(pm2 指定配置文件
启动服务):
// package.json
"scripts": {
"start": "nodemon ./bin/www",
+"pro": "pm2 start ./pm2.config.json"
},
增加如下路由,用于测试日志
:
// localhost:3000/users/testlog
router.get('/testlog', function(req, res, next) {
// 输出到自定义日志中
console.log('信息');
// 输出到错误日志中
console.error('错误信息');
res.send({"status":0,"msg":"123","data":{}});
});
通过 npm run pro
启动服务:
PS E:\pjl-back-end> npm run pro
> [email protected] pro
> pm2 start ./pm2.config.json
[PM2][WARN] Applications spug-back-end not running, starting...
[PM2] App [spug-back-end] launched (2 instances)
┌────┬──────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬───
───────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼──────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼───
───────┼──────────┼──────────┤
│ 0 │ spug-back-end │ default │ 0.0.0 │ cluster │ 12496 │ 0 │ 1 │ stopped │ 0% │ 0b │ Adm… │ enabled │
│ 1 │ spug-back-end │ default │ 0.0.0 │ cluster │ 11436 │ 0 │ 1 │ stopped │ 0% │ 0b │ Adm… │ enabled │
└────┴──────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴───
───────┴──────────┴──────────┘
// 启动后立刻执行
PS E:\pjl-back-end> npx pm2 list
┌────┬──────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬───
───────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼──────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼───
───────┼──────────┼──────────┤
│ 0 │ spug-back-end │ default │ 0.0.0 │ cluster │ 1396 │ 14s │ 1 │ online │ 0% │ 58.7mb │ Adm… │ enabled │
│ 1 │ spug-back-end │ default │ 0.0.0 │ cluster │ 1704 │ 14s │ 1 │ online │ 0% │ 58.7mb │ Adm… │ enabled │
└────┴──────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴───
───────┴──────────┴──────────┘
PS E:\pjl-back-end>
应用名是 spug-back-end
。
启动了两个应用,说明 "instances": 2
已生效。
logs 文件夹中生成了4个日志文件(每个cpu核就是两个),文件名也是我们配置的,目前日志内容都为空:
$ ll logs
total 0
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 custom-0.log
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 custom-1.log
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 error-0.log
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 error-1.log
访问 http://localhost:3000/
页面显示正常:
Express
Welcome to Express
再次查看日志发现 custom-1.log
有内容,记录了着请求的详细信息。例如时间
、请求的资源(/stylesheets/style.css
):
Administrator@3L-WK-10 MINGW64 /e/pjl-back-end (master)
$ ll logs
total 1
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 custom-0.log
-rw-r--r-- 1 Administrator 197121 144 May 9 16:42 custom-1.log
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 error-0.log
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 error-1.log
Administrator@3L-WK-10 MINGW64 /e/pjl-back-end (master)
$ cat logs/custom-1.log
2023-05-09 16:42:35: GET / 304 21.595 ms - -
2023-05-09 16:42:35: GET /stylesheets/style.css 304 3.358 ms - -
修改某请求响应:
$ git diff routes/index.js
router.get('/', function(req, res, next) {
- res.render('index', { title: 'Express' });
+ res.render('index', { title: 'Express2' });
});
再次访问 http://localhost:3000/
修改信息自动生效:
Express2
Welcome to Express2
通过 npx pm2 list
发现服务自动重启了(↺ 1 -> 3
):
PS E:\pjl-back-end> npx pm2 list
┌────┬──────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬───
───────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼──────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼───
───────┼──────────┼──────────┤
│ 0 │ spug-back-end │ default │ 0.0.0 │ cluster │ 13868 │ 89s │ 3 │ online │ 0% │ 60.5mb │ Adm… │ enabled │
│ 1 │ spug-back-end │ default │ 0.0.0 │ cluster │ 11792 │ 89s │ 3 │ online │ 0% │ 61.1mb │ Adm… │ enabled │
└────┴──────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴───
再次查看日志,发现 custom-0.log 也有数据了,这里其实间接说明了一个负载均衡
的问题,这两个应用都能提供服务。
$ ll logs
total 2
-rw-r--r-- 1 Administrator 197121 228 May 9 16:46 custom-0.log
-rw-r--r-- 1 Administrator 197121 144 May 9 16:42 custom-1.log
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 error-0.log
-rw-r--r-- 1 Administrator 197121 0 May 9 16:40 error-1.log
接着访问输出日志的请求:http://localhost:3000/users/testlog
,发现在同一时刻(16:54:47
)往 custom-0.log 输出了 信息
,在 error-0.log 中输出了 错误信息
:
$ git diff logs
--- a/logs/custom-0.log
+++ b/logs/custom-0.log
2023-05-09 16:53:56: GET /users/testlog 304 14.507 ms - -
+2023-05-09 16:54:47: 信息
+2023-05-09 16:54:47: GET /users/testlog 304 9.892 ms - -
--- a/logs/error-0.log
+++ b/logs/error-0.log
2023-05-09 16:53:56: 错误信息
+2023-05-09 16:54:47: 错误信息
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK