如何使用node.js设置脚本的最长执行时间?

时间:2013-03-02 16:15:45

标签: node.js execution-time

我为用户提供了一种灵活的方式来使用JavaScript转换数据,在服务器端使用Node.js执行。有了这个设计,需要考虑3个问题:

  • 安全性:我使用sandbox解决了安全问题,以避免使用本机Node.js库。

  • 资源:我们可以使用v8选项--max_executable_size轻松设置最大内存使用量。关于CPU使用情况,我会看到如何使用cpulimitrenice来管理它,现在并不重要。

  • 时间:我需要限制脚本的执行时间,以避免它们作为hangry zombies运行。在这里,我卡住了。

我尝试过类似的事情:

 node -e '
    setTimeout(function() {
       console.log("timeout");
       process.exit;
    }, 5000);
    console.log("begin");
    while (1);
 '

但是这段代码只显示“开始”,似乎我的超时从未被调用过。 有什么想法吗?

3 个答案:

答案 0 :(得分:7)

你可能想看看tripwire(https://github.com/tjanczuk/tripwire)。它是一个可以杀死失控节点脚本的模块,您可以设置超时。它是一个本机节点模块,因此这是一件需要考虑的事情,但它适用于Mac,Windows和Linux。

答案 1 :(得分:4)

不幸的是,如果您的用户可以启动阻止操作(例如while(1)),则无法告知Node在一定时间后退出,因为阻止操作将阻止setTimeout处理程序触发。确保用户启动的东西不会阻塞主循环,或者(这是非常坏主意)使用某种外部自动终止/超时来破坏Node进程。

基本上,您可以使用Node来限制非阻塞代码的执行时间,但Node的重点是阻止代码阻止所有内容。如果您的用户真的能够运行任意代码,我会考虑在更高级别运行您的进程管理器/超时杀手:例如,使用Node的exec工具生成具有终止超时的进程。

答案 2 :(得分:1)

节点built-in vm module提供module.evaluatescript.runInContext以及其他一些方法,这些方法将在沙盒环境中运行代码,并使用timeout选项指定最长时间(在ms)允许VM运行。

请注意,在Node.js中运行不受信任的代码充满了潜在的安全问题。甚至VM模块也明确说“ vm模块不是安全机制。不要用它来运行不受信任的代码。”(为什么不呢?Here is one reason why not:它看起来应该是无害的运行vm.runInNewContext("this.constructor.constructor('return process')().exit()")但事实上它会导致Node终止。

您也可以考虑使用提供类似功能的Patrik Simek vm2,但声称“使用列入白名单的Node的内置模块运行不受信任的代码。安全!”文档中的一个例子:

const {VM} = require('vm2');

const vm = new VM({
    timeout: 1000,
    sandbox: {}
});

vm.run("process.exit()"); // throws ReferenceError: process is not defined