pm2-perfmonitor 1.1.2 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -9
- package/lib/app.js +21 -3
- package/lib/pm2-extra.js +37 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,15 +17,16 @@ $ pm2 install pm2-perfmonitor
|
|
|
17
17
|
|
|
18
18
|
# Configure
|
|
19
19
|
|
|
20
|
-
| Property | Default Value |
|
|
21
|
-
| :-----------------------------: | :-----------: |
|
|
22
|
-
| `enabled` | `true` |
|
|
23
|
-
| `excludeApps` | - |
|
|
24
|
-
| `includeApps` | - |
|
|
25
|
-
| `workerInterval` | `60000` |
|
|
26
|
-
| `zombieDetection` | `true` |
|
|
27
|
-
| `zombieMaxHits` | `10` |
|
|
28
|
-
| `autoRestartWhenZombieDetected` | `true` |
|
|
20
|
+
| Property | Default Value | Description |
|
|
21
|
+
| :-----------------------------: | :-----------: | :----------------------------------------------------------------------------------: |
|
|
22
|
+
| `enabled` | `true` | Specify whether to enable this module |
|
|
23
|
+
| `excludeApps` | - | Specify the application name that needs to be excluded from guardianship |
|
|
24
|
+
| `includeApps` | - | Specify the application name that needs to be guarded |
|
|
25
|
+
| `workerInterval` | `60000` | Timed task execution interval (ms) |
|
|
26
|
+
| `zombieDetection` | `true` | Specify whether to enable zombie process protection |
|
|
27
|
+
| `zombieMaxHits` | `10` | Specify the maximum occurrence frequency of zombie status |
|
|
28
|
+
| `autoRestartWhenZombieDetected` | `true` | Specify whether to automatically restart zombie processes |
|
|
29
|
+
| `zombieMaxRestarts` | `0` | The maximum number of zombie process restarts can be set to `0` to indicate no limit |
|
|
29
30
|
|
|
30
31
|
# How to set these values ?
|
|
31
32
|
|
package/lib/app.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const pmx = require('pmx')
|
|
2
2
|
const pm2 = require('pm2')
|
|
3
|
+
const { getPm2ListAsync } = require('./pm2-extra')
|
|
3
4
|
const { parseParamToArray, parseParamToNumber, parseBool } = require('./utils')
|
|
4
5
|
|
|
5
6
|
const defaultOptions = {
|
|
@@ -28,6 +29,10 @@ const defaultOptions = {
|
|
|
28
29
|
* 僵尸状态达到最大容忍度时,是否自动重启僵尸进程
|
|
29
30
|
*/
|
|
30
31
|
autoRestartWhenZombieDetected: true,
|
|
32
|
+
/**
|
|
33
|
+
* 僵尸进程最大重启次数,设置为0表示不限制
|
|
34
|
+
*/
|
|
35
|
+
zombieMaxRestarts: 0,
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
const conf = pmx.initModule({}, (err, incomingConf) => {
|
|
@@ -53,6 +58,7 @@ const AUTO_RESTART_WHEN_ZOMBIE_DETECTED = parseBool(
|
|
|
53
58
|
conf.autoRestartWhenZombieDetected,
|
|
54
59
|
)
|
|
55
60
|
const ZOMBIE_MAX_HITS = parseParamToNumber(conf.zombieMaxHits)
|
|
61
|
+
const ZOMBIE_MAX_RESTARTS = parseParamToNumber(conf.zombieMaxRestarts)
|
|
56
62
|
|
|
57
63
|
// 存储每个进程的 CPU 采样历史(pm_id -> [cpu1, cpu2, ...])
|
|
58
64
|
const cpuHistory = new Map()
|
|
@@ -69,6 +75,7 @@ const logger = (type, ...args) => {
|
|
|
69
75
|
|
|
70
76
|
/**
|
|
71
77
|
* 判断是否为僵尸进程:最近 ZOMBIE_MAX_HITS 次全是 0%
|
|
78
|
+
* @param { number[] } history
|
|
72
79
|
*/
|
|
73
80
|
const isZombie = (history) => {
|
|
74
81
|
return history.length >= ZOMBIE_MAX_HITS && history.every((v) => v === 0)
|
|
@@ -77,10 +84,12 @@ const isZombie = (history) => {
|
|
|
77
84
|
/**
|
|
78
85
|
* check zombie process
|
|
79
86
|
*/
|
|
80
|
-
const zombieProcessChecker = () => {
|
|
87
|
+
const zombieProcessChecker = async () => {
|
|
81
88
|
if (!ZOMBIE_DETECTION) return
|
|
82
89
|
|
|
83
|
-
|
|
90
|
+
try {
|
|
91
|
+
const apps = await getPm2ListAsync()
|
|
92
|
+
|
|
84
93
|
apps.forEach((app) => {
|
|
85
94
|
const { name, pm_id, monit, pm2_env } = app
|
|
86
95
|
|
|
@@ -121,6 +130,13 @@ const zombieProcessChecker = () => {
|
|
|
121
130
|
logger('info', `Zombie detected: ${name} (pm_id: ${pm_id})`)
|
|
122
131
|
|
|
123
132
|
if (AUTO_RESTART_WHEN_ZOMBIE_DETECTED) {
|
|
133
|
+
if (
|
|
134
|
+
ZOMBIE_MAX_RESTARTS > 0 &&
|
|
135
|
+
zombieRestartHistory.get(pm_id) >= ZOMBIE_MAX_RESTARTS
|
|
136
|
+
) {
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
124
140
|
logger('info', 'restarting...')
|
|
125
141
|
|
|
126
142
|
pm2.restart(pm_id, (restartErr) => {
|
|
@@ -162,7 +178,9 @@ const zombieProcessChecker = () => {
|
|
|
162
178
|
}
|
|
163
179
|
}
|
|
164
180
|
})
|
|
165
|
-
})
|
|
181
|
+
} catch (err) {
|
|
182
|
+
logger('error', err)
|
|
183
|
+
}
|
|
166
184
|
}
|
|
167
185
|
|
|
168
186
|
const runModule = () => {
|
package/lib/pm2-extra.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const pm2 = require('pm2')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @returns { Promise<pm2.ProcessDescription[]> }
|
|
5
|
+
*/
|
|
6
|
+
const getPm2ListAsync = () => {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
pm2.list((err, apps) => {
|
|
9
|
+
if (err) {
|
|
10
|
+
return reject(err)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
resolve(apps)
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param { string | number} pm_id
|
|
20
|
+
* @returns { Promise<void> }
|
|
21
|
+
*/
|
|
22
|
+
const pm2StopAsync = (pm_id) => {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
pm2.stop(pm_id, (err) => {
|
|
25
|
+
if (err) {
|
|
26
|
+
return reject(err)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
resolve()
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = {
|
|
35
|
+
getPm2ListAsync,
|
|
36
|
+
pm2StopAsync,
|
|
37
|
+
}
|