上傳、下載和發(fā)布
前面我們已經(jīng)完成了數(shù)據(jù)庫的增刪改查
,在弄一個上傳
圖片、下載
csv,一個最簡單的后臺開發(fā)就已完成,最后部署
即可。
上傳圖片
需求
需求
:做一個個人簡介
的表單提交,有昵稱
、簡介
和頭像
。后端能接收數(shù)據(jù)并保存到數(shù)據(jù)庫。
接收不到數(shù)據(jù)
用 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
是空對象,說明無法接收數(shù)據(jù):
req {}
POST /users/upload 200 6.230 ms - 31
前端傳輸數(shù)據(jù)如下:
如果前端不傳文件
,后端 req.body 則能正常接收數(shù)據(jù):
req { nickname: 'pjl', introduction: 'i am pjl', file: '' }
POST /users/upload 200 26.287 ms - 31
Tip:Content-Type 用于指示資源的 MIMIE 類型,請求中,客戶端告訴服務(wù)器實際發(fā)送的數(shù)據(jù)類型。相應(yīng)中,告訴客戶端發(fā)送的內(nèi)容的內(nèi)容類型。不傳文件請求頭的 Content-Type 是 Content-Type: application/json
;傳了文件,請求頭的 Content-Type 是 Content-Type: multipart/form-data; boundary=----
。需要在表單中進行文件上傳時,就需要使用該格式:multipart/form-data
。
multer
Multer 是一個 node.js 中間件,用于處理 multipart/form-data
類型的表單數(shù)據(jù),它主要用于上傳文件。
注:Multer 不會處理任何非 multipart/form-data 類型的表單數(shù)據(jù)
安裝 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')
+// 啟動服務(wù)后,自動在 public 下創(chuàng)建 uploads 文件夾
+const upload = multer({ dest: 'public/uploads/' })
+// 一旦請求過來,就會先經(jīng)過中間件把接收到的圖片存入 uploads 文件夾中,然后在到下一步
+// file 是前端文件的 name。由于這里是一張圖片,所以用 single 方法。多張圖片的使用請看文檔
+router.post('/upload', upload.single('file'), function(req, res, next) {
+ // req.body 將具有文本域數(shù)據(jù),如果存在的話
+ console.log(req.body)
+ // req.file 是 `file` 文件的信息
+ console.log(req.file)
res.send({"status":0,"msg":"","data":{}});
});
啟動服務(wù)后,會自動
在 public 下創(chuàng)建 uploads
文件夾。輸入昵稱、簡介和頭像,點擊提交。頭像文件會重命名并上傳到 uploads 中,通過 req.body
可以取得昵稱和簡介,通過 req.file
可以取得文件信息。后續(xù)存入數(shù)據(jù)庫的操作筆者就不在進行,無非就是通過 token 取得用戶 id,然后將昵稱、簡介和頭像路徑傳給 services,通過 model 保存到數(shù)據(jù)庫。
Tip:雖然文件沒有了后綴(.png),通過chrome 直接訪問圖片路徑(http://localhost:3000/uploads/36d8bda3160d8d09e81b167de1969b47
)會自動下載,把圖片路徑給到 image 是可以正常使用。
下載csv
需求
需求
:點擊導(dǎo)出全部
按鈕,發(fā)起請求,通過后端直接下載 csv 文件,里面是表格數(shù)據(jù)。
實現(xiàn)
安裝 json2csv
包,用于將數(shù)據(jù)庫中查詢的 json 轉(zhuǎn)為 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
用于編碼轉(zhuǎn)換:
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,導(dǎo)出 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 轉(zhuǎn)碼,防止中文亂碼
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'
},
];
// 模擬從數(shù)據(jù)庫查詢出的數(shù)據(jù)
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);
});
重啟服務(wù),瀏覽器輸入 localhost:3000/users/download
回車后會自動下載 csv 文件。雙擊打開 csv,效果如下:
如果不轉(zhuǎn)碼處理,這里 csv 中的中文就會亂碼。
疑惑
:網(wǎng)上說 gbk和utf8都是都能編碼中英文。將 gbk 改為 utf8
,在 win7 中打開 csv 仍舊亂碼,或許是win7 中打開csv是gbk,得保持客戶端和服務(wù)器編碼一致?
發(fā)布
pm2
假如 node 項目已經(jīng)開發(fā)完畢,得將應(yīng)用部署到服務(wù)器中。
直接使用 node app.js
一旦關(guān)閉終端,服務(wù)就會中斷
雖然也可以使用 node app.js &
后臺啟動服務(wù),但也有很多不足,比如重新發(fā)布代碼不會自動生效
Tip: windows 下關(guān)閉后臺啟動的服務(wù),比如端口是 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
常用于開發(fā)環(huán)境
筆者這里使用 pm2。有如下好處:
- 監(jiān)控服務(wù)資源
- 發(fā)布代碼、宕機后會自動重啟
- 比如你的是cpu 是4核,也能充分利用
- 能查看日志
體驗 pm2
全局安裝 pm2
PS E:\pjl-back-end> npm install pm2 -g
npm WARN deprecated uuid@3.4.0: 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 啟動服務(wù):
Tip: 筆者由于環(huán)境問題,使用 npx 運行 pm2。你們可以省略。
查看版本
通過 pm2 --version
查看版本,說明安裝成功:
PS E:\pjl-back-end> npx pm2 --version
5.3.0
啟動服務(wù)
通過 pm2 start 入口文件
啟動服務(wù):
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 │
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──
────────┴──────────┘
應(yīng)用的 id
是 0,name
是 www,后續(xù)刪除、啟動和重啟應(yīng)用使用 id 和 name 都可以。
?
表示重啟次數(shù)為0。后續(xù)重啟應(yīng)用會自動增加。
status 中的 online
表示已上線。
服務(wù)列表
通過 pm2 list
顯示應(yīng)用列表,比如目前有一個服務(wù)(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 │
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──
────────┴──────────┘
重啟服務(wù)
通過 pm2 restart id|name
重啟服務(wù):
// 通過 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: ?
表示重啟過幾次了
應(yīng)用詳情
pm2 info www
查看 www 這個應(yīng)用的詳細(xì)信息:
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 │ 取消數(shù)據(jù)庫和登錄標(biāo)識 │
│ 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
監(jiān)控應(yīng)用
通過 pm2 monit id|name
監(jiān)控應(yīng)用程序:
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輸出的內(nèi)容,下文配置 pm2
會講到。
停止應(yīng)用
通過 pm2 stop id|name
停止服務(wù):
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 │
└────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──
────────┴──────────┘
關(guān)閉并刪除應(yīng)用
通過 pm2 delete id|name
關(guān)閉并刪除應(yīng)用:
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 │
└────┴───────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────
┴──────────┴──────────┘
穩(wěn)定的服務(wù)
比如筆者寫一個如下服務(wù) 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('服務(wù)器已啟動')
})
通過 node app2.js
啟動服務(wù)后,訪問 localhost:3000/error
故意報錯,服務(wù)就會死掉,無法在響應(yīng)其他請求:
PS E:\pjl-back-end> node app2.js
服務(wù)器已啟動
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
啟動服務(wù):
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
發(fā)現(xiàn)重啟(?
)次數(shù)從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
,說明服務(wù)正常,也較之前更穩(wěn)定。
配置 pm2
需求
需求
:配置應(yīng)用名稱
、入口文件
、監(jiān)控
、日志
、實例數(shù)
代碼
項目根目錄新建 pm2 配置文件 pm2.config.json
:
{
"apps": {
// 應(yīng)用名稱
"name": "spug-back-end",
// 入口文件
"script": "./bin/www",
// 監(jiān)控。修改代碼后自動生效
"watch": true,
// 排除某些文件的監(jiān)控
"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 核數(shù)。不要超過服務(wù)器的 cpu 核數(shù)
// 筆者 cpu 核數(shù)是 2,這樣會啟動 2 個服務(wù),能更好的利用服務(wù)器資源。
"instances": 2
}
}
Tip:windows 查看 CPU 核數(shù) - 在 cmd 命令中輸入 wmic
,然后在出現(xiàn)的新窗口中輸入 cpu get NumberOfCores
:
PS E:\pjl-back-end> wmic
wmic:root\cli>cpu get NumberOfCores
NumberOfCores
2
修改 package.json(pm2 指定配置文件
啟動服務(wù)):
// 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
啟動服務(wù):
PS E:\pjl-back-end> npm run pro
> pjl-back-end@0.0.0 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 │
└────┴──────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴───
───────┴──────────┴──────────┘
// 啟動后立刻執(zhí)行
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>
應(yīng)用名是 spug-back-end
。
啟動了兩個應(yīng)用,說明 "instances": 2
已生效。
logs 文件夾中生成了4個日志文件(每個cpu核就是兩個),文件名也是我們配置的,目前日志內(nèi)容都為空:
$ 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
再次查看日志發(fā)現(xiàn) custom-1.log
有內(nèi)容,記錄了著請求的詳細(xì)信息。例如時間
、請求的資源(/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 - -
修改某請求響應(yīng):
$ 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
發(fā)現(xiàn)服務(wù)自動重啟了(? 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 │
└────┴──────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴───
再次查看日志,發(fā)現(xiàn) custom-0.log 也有數(shù)據(jù)了,這里其實間接說明了一個負(fù)載均衡
的問題,這兩個應(yīng)用都能提供服務(wù)。文章來源:http://www.zghlxwxcb.cn/news/detail-437412.html
$ 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
,發(fā)現(xiàn)在同一時刻(16:54:47
)往 custom-0.log 輸出了 信息
,在 error-0.log 中輸出了 錯誤信息
:文章來源地址http://www.zghlxwxcb.cn/news/detail-437412.html
$ 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: 錯誤信息
到了這里,關(guān)于Node + Express 后臺開發(fā) —— 上傳、下載和發(fā)布的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!