В данном случае у меня есть мастер-кластер, cluster.isMaster
, который будет порождать сотни рабочих, cluster.isWorker
, но только 4 рабочих должны быть живы в любой момент времени (чтобы ограничить использование ресурсов).
Прежде чем я внес какие-либо изменения в мастер-кластер, все работало, как и ожидалось, и плавно, , но , затем я заметил, что когда я запускаю node app.js
из терминала, а затем нажимаю Ctrl+C
только основнойрабочий процесс будет принудительно убит, в то время как активный рабочий процесс все еще работает в фоновом режиме, и я использую Ubuntu 18.04 в качестве ОС. Так что тогда мне придется вручную убить рабочий процесс, используя kill workerProcessID
на моем компьютере.
Из-за этих ограничений я внедряю этот фрагмент в код своего мастер-кластера
Snippet A
let killWorkers = () => {
for (let id in cluster.workers) {
cluster.workers[id].kill();
console.log(id);
}
};
process.on('exit', killWorkers);
process.on("uncaughtException", killWorkers);
process.on("SIGINT", killWorkers);
process.on("SIGTERM", killWorkers);
реализуя этот фрагмент, я надеюсь, что каждый раз, когда я вводю Ctrl+C
на терминале, он мгновенно убивает весь процесс Master и Worker.
На самом деле это работает, каждый раз, когда я нажимаю Ctrl+C
на терминале, это также убивает процесс Workers. на заднем плане.
Но у меня есть другое странное поведение после его реализации, это странное поведение, я не могу найти аналогичный случай или какое-либо решение в сети.
Позвольте сказатьв определенный момент времени мастер-процесс уже породил 16 рабочих, и эти рабочие уже убили программно (выполняя process.kill()
внутри рабочих), теперь активными рабочими являются рабочие № 17-20, если сейчас я нажму Ctrl+C
, это убьет тех,работник № 17-20, но затем он создаст экземпляр работника № 21-24, поэтому мне нужно нажать еще один Ctrl+C
и т. д. и так далее, если, скажем, у меня 100 рабочих в очереди, то я должен нажимать Ctrl+C
несколько раз.
Второе поведение является наиболее тревожным и трудным для понимания в работнике. процесс я реализую что-то вроде этого:
let workerFunc = () => {
console.log("Worker " + process.pid + " has started.");
process.on("message", async msg => {
console.log("Receiving Message");
process.kill();
})
}
в мастер-кластере:
cluster.on("exit", async (wk, code, signal) => {
console.log(`Worker: ${wk.process.pid} just DIED`);
if (pendingWorkers.length > 0) {
let worker = cluster.fork();
worker.send({
workerPID: worker.process.pid,
msg: "Hello"
});
}
}
Теперь, еслискажем, я жду, пока весь процесс не завершится, то есть, пока все 100 рабочих не начнут и не будут убиты, некоторые из этих работников действуют странно , из этих сотен рабочих некоторые могут выполнитьследующая строка console.log("Receiving Message");
, но большинство будет только log console.log("Worker " + process.pid + " has started.");
, а затем насильно убито, прежде чем попасть в console.log("Receiving Message");
.
Даже после того, как я отключу Snippet A
, оно все равно будет иметь странное поведениемногие работники не выполняют код после process.on('message',...)
, даже после того, как я скопировал код в новый файл, он по-прежнему действовал так, даже после того, как я очищал кэш-память ОЗУ, даже после перезагрузки компьютера код по-прежнему работал странно, я просто хочувернуться назад до того, как я реализую Snippet A
, то есть все работники смогут выполнить команду после process.on('message',...)
.
Как мне решить эти проблемы? Спасибо