上傳、下載和釋出
前面我們已經完成了資料庫的增刪改查
,在弄一個上傳
圖片、下載
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,得保持客戶端和伺服器編碼一致?
釋出
pm2
假如 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 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 啟動服務:
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
> 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 │
└────┴──────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴───
───────┴──────────┴──────────┘
// 啟動後立刻執行
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: 錯誤資訊