АлиeggjsОдним из основных являетсяegg-clusterЧтобы сделать основной процесс запуска, общение внутри довольно интересное. Внимательно изучил официальные nodejsclusterплюс яйцаAgent
Концепция, если вы хотите поддерживать связь, вам все равно придется наступить на много ям. Эта яма на самом деле происходит отcluster
сам. Если вы просто исследуетеcluster
, так много людей смущены этим, как это отслеживать и отправлять?
концепция
Сначала разберитесь с некоторыми понятиями:
-
masterосновной процесс
cluster.isMaster
определенный процесс -
workerдочерний процесс
cluster.isWorker
определенный процесс - agentПроцесс, созданный child_process
Чтобы общаться друг с другом по этим процессам, нам нужно выяснить, как отправлять.
- Рабочий взаимодействует с агентом и нуждается в мастере в качестве моста для транзита.
- Рабочий общается с мастером
- Мастер общается с рабочими
- Связь между мастером и агентом
- агент общается с мастером
- Агент общается с воркером, а мастер нужно использовать как мост для передачи
Как заставить его общаться идеально, я рекомендую библиотеку здесьGitHub.com/CE vi O/IPC — нет…. Он позволяет вам привязать к себе все события без восприятия, и при этом открыть канал сообщений.
Создайте
Это класс, который необходимо наследовать для использования.
const IPCMessage = require('ipc-message');
module.exports = class NodeBase extends IPCMessage {
constructor() {
// If it is a `agent` type process, you need to set the parameter to `true`.
// super(true);
super();
// receive message from other processes.
this.on('message', msg => {
console.log(`[${this.type}] Receive Message:`, msg);
});
if (this.type === 'master') {
// do master ...
} else {
// do worker
}
}
}
мы связываемmessage
события для получения сообщений черезregistAgent
Для регистрации агента черезcluster.fork()
Чтобы создать дочерний процесс, конечно, это создание автоматически контролируется, вам не нужно заботиться.
Информация
Проще говоря, они отправляют сообщения через метод send в произвольном коде. Например, приведенный выше пример (при условии, что имя было задано какstaticAgent
агент и установил 4 воркера, теперь по коду который воркер запускает):
const base = new NodeBase();
base.send('staticAgent', 'worker-ready', {
a: 1,
b: 2
});
Агент получает информацию через переадресацию мастера
[staticAgent] agent receive message:
{
to: [19678],
from: 19679,
transfer: true,
action: 'worker-ready',
body: {
a: 1,
b: 2
}
}
Вы можете анализировать это через эти данные, и как это решить, зависит от ваших личных мыслей.
использовать
Давайте посмотрим на 2 фактических фрагмента кода
test/index.js
const IPCMessage = require('ipc-message');
const ChildProcess = require('child_process');
const path = require('path');
const cluster = require('cluster');
const Koa = require('koa');
const os = require('os');
class Nodebase extends IPCMessage {
constructor() {
super();
if (this.type === 'master') {
const agentWorkerRuntimeFile = path.resolve(__dirname, 'agent.js');
// 创建一个agent
const agent = ChildProcess.fork(agentWorkerRuntimeFile, null, {
cwd: process.cwd(),
stdout: process.stdout,
stderr: process.stderr,
stdin: process.stdin,
stdio: process.stdio
});
// 注册该agent
this.registAgent('agent', agent);
let cpus = os.cpus().length;
while (cpus--) {
// 根据内核数来创建子进程
cluster.fork();
}
} else {
// 以下为实际开发的代码
const app = new Koa();
app.use(async (ctx, next) => {
if (ctx.req.url === '/favicon.ico') return;
this.send('agent', '/test/agent', { a:1, c:3 });
ctx.body = 'hello world';
});
app.listen(3000, () => {
console.log('server start at 3000');
});
}
this.on('message', msg => {
console.log(`[${this.type}] onMessageReceive:`, msg);
});
}
}
const nodebase = new Nodebase();
if (nodebase.type === 'master') {
setTimeout(() => {
// 发送消息给agent
nodebase.send('agent', '/a/b', {
a:1
});
}, 5000)
}
test/agent.js
const IPCMessage = require('ipc-message');
class Agent extends IPCMessage {
constructor() {
// 如果是个agent启动的文件,这里必须为true
super(true);
this.timer = setInterval(() => {
console.log('agent alive');
}, 1000);
process.on('SIGINT', () => {
clearInterval(this.timer);
process.exit(0);
});
this.on('message', msg => {
console.log('[Agent] onMessageReceive:', msg);
this.send([msg.from, 'master'], '/reply/agent', 'done');
})
}
}
const agent = new Agent();
// 发送消息
agent.send('master', '/agent/ready', { a: 1, b: 2 });
наконец
С упрощенным модулем для обработки связи вы также можете попробовать использовать его для создания процесса запуска, подобного яйцу, и основной запуск яйца больше не является загадочным.