节点集群派生执行代码过于频繁

时间:2019-02-18 08:13:55

标签: node.js worker

我有一些要在单独的线程中执行的作业(功能)。因此,我创建了一个实用程序函数来完成此操作:

import {cpus} from "os"
import cluster from 'cluster'

export default function runInThread(func: Function, useAllCores = false, numThreads = useAllCores ? cpus().length : 1) {
    if(cluster.isMaster) {
        for(let i = 0; i < numThreads; i++) {
            cluster.fork()
        }
    } else {
        func()
    }
}

然后我要执行以下工作:

import runInThread from "../helpers/threading"
import job1 from "./job1"
import job2 from "./job2"

let jobs = [
    job1, 
    job2
]

jobs.forEach(job => runInThread(job))

示例作业是:

export default function job1() {
    console.log('job1')
}

export default function job2() {
    console.log('job2')
}

不幸的是,由于输出为:

job1
job1
job2
job2

所以似乎每个工作都会被分两次……?

2 个答案:

答案 0 :(得分:1)

您所说的完全正常。而且只产生了两个工人。

您可以通过在作业中打印工人ID来确认这一点:

import cluster from 'cluster';

export default function job1() {
  console.log(`WORKER #${cluster.worker.id}: job1`);
};

一旦您调用fork,它将产生一个新的node.js进程(顺便说一句不是线程)并再次执行您的代码。这意味着您的每个工人都将有效执行以下操作:

import {cpus} from "os"
import cluster from 'cluster'
import job1 from "./job1"
import job2 from "./job2"

function runInThread(func, useAllCores = false, numThreads = useAllCores ? cpus().length : 1) {
    func()
}

let jobs = [
    job1,
    job2
]

jobs.forEach(job => runInThread(job))

因此每个工作人员将记录:

job1
job2

并退出。另外,由于它们是在两个不同的进程中执行的,因此日志消息可能会交错。

答案 1 :(得分:0)

主要思想-每个线程(分支)都像主机一样执行某些功能。在示例中,这只是函数名称,但是在实际工作中,您可以为函数生成一些id并将其作为env变量传递给worker。

import {cpus} from "os"
import cluster from 'cluster'

export default function runInThread(func: Function, useAllCores = false, numThreads = useAllCores ? cpus().length : 1) {
    if(cluster.isMaster) {
        for(let i = 0; i < numThreads; i++) {
            cluster.fork({FUNC_ID: func.name})
        }
    } else {
       if (process.env.FUNC_ID === func.name) {
         func()
       }
    }
}