使用Koa框架无法杀死Node.js集群中的特定工作者

时间:2018-08-17 15:21:04

标签: node.js multithreading cluster-computing koa

我们正在使用FFI节点模块从Node.js服务器使用c ++ dll。 C ++ dll公开了Node.js服务器正在使用的许多功能。

在某些特殊情况下,C ++ dll具有卡住的特征。到目前为止,我们还没有一种机制可以从C ++ dll中进行修复。因此,即将到来的请求将无法得到解决,因为dll是单线程的,一次只能接受一个请求。

之所以必须使用cluster-worker拓扑是因为我们想从外部控制dll。

我们创建了固定数量的叉子/工人,它们在一个池中。对于每个传入的请求,我们将请求分配给一个新的工作程序,并将该工作程序与dll一起使用。每当看到工人花费的时间超过“健康”的时间时,我们都希望杀死它。

我们面临一个特定的问题,如果该工人因C ++ dll无法响应而陷入困境,我们将无法杀死该工人。这是必需的,因为c ++ dll中存在未处理的情况。

我们引用了Node.js集群模块的代码- https://nodejs.org/api/cluster.html#cluster_worker_process

这是我们的代码段-

server_fork.js

var chalk = require( "chalk" );
var cluster = require( "cluster" );
var os = require( "os" );

if ( cluster.isMaster ) {
    console.log( chalk.red( "[Cluster]" ), "Master process is now running.", process.pid );

    for ( var i = 0, coreCount = 2; i < coreCount ; i++ ) {
        var worker = cluster.fork();
    }

    function messageHandler(msg) {
        console.log('messageHandler')
        if (msg.cmd && msg.cmd === 'notifyRequest') {
          numReqs += 1;
        }
      }


    cluster.on(
        "exit",
        function handleExit( worker, code, signal ) {

            console.log( chalk.yellow( "[Cluster]" ), "Worker has died.", worker.process.pid );
            console.log( chalk.yellow( "[Cluster]" ), "Death was suicide:", worker.exitedAfterDisconnect );

                var worker = cluster.fork();
                console.log('new thread');
        }
    );

    cluster.on(
        "message",
        function handleExit( worker, code, signal ) {
            let timeout
            if (code.cmd == 'started'){
                worker.toBeKilled = true
                timeout = setTimeout(() => {
                    if(worker.toBeKilled){
                        try{
                        console.log('inside worker to be killed')
                        // worker.disconnect()
                        worker.kill()
                        //process.exit(0)
                        // process.exit()
                        }catch(err){
                            console.log('err',err)
                        }

                    }
                  }, 2000);
            } else {
                worker.toBeKilled = false
            }


        }
    );
    function messageHandler(msg) {
        if (msg.cmd && msg.cmd === 'notifyRequest') {
            console.log('notifyRequest');
        }
      }

} else {

    require( "./server" );
    console.log( chalk.red( "[Worker]" ), "Worker has started.", process.pid );
}

server.js

const Koa = require('koa');
var mount = require('koa-mount');
var serve = require('koa-static');
var bodyParser = require('koa-bodyparser');
var koaBody = require('koa-body');
var api = require('./../src/modules/bvp/router.js');
var jwt = require('koa-jwt');

const app = new Koa();
var hbs = require('koa-hbs');
const convert = require('koa-convert');
const co = require('co');

app.use(convert(hbs.middleware({
  viewPath: __dirname + '/../src/views',
})));

app.use(async (ctx, next) => {
  const render = ctx.render;
  ctx.render = async function _convertedRender () {
    return co.call(ctx, render.apply(ctx, arguments));
  }
  await next();
});

if (!process.env.NODE_ENV || process.env.NODE_ENV === 'devlopment') {
  app.use(mount('/swagger', serve(`${process.cwd()}/../swagger`)))
}

app.use(koaBody());
app.use(bodyParser());
app.use(api.routes());

app.listen(3000, function() {
console.log('server started on port 3000');
});


module.exports = app;

controller.js

var som_lib = require('som_lib.js');
const Promise = require('promise');
async function simulate(ctx) {
    var arr = [];
    process.send({ cmd: 'started' });
    var output = som_lib.playLeague();
    process.send({ cmd: 'end' });
    ctx.body = output;
}
module.exports = {
    simulate: simulate
}

在超时的情况下,当我们试图杀死该特定工人时,我们会收到以下错误-

err { Error: kill ESRCH
at exports._errnoException (util.js:1050:11)
at process.kill (internal/process.js:188:13)
at Timeout.setTimeout [as _onTimeout] (C:\Data\projects\BVP_backend - Copy\bin\server_fork.js:65:33)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5) code: 'ESRCH', errno: 'ESRCH', syscall: 'kill' }

我们已经在Express框架中提到了类似的问题-链接 Can't kill a specific worker in Node JS cluster

0 个答案:

没有答案