最近登录到我们前端沙盒机器
上去的时候,偶尔碰到-bash: fork retry: Resource temporarily unavailable这样的错误,过一会儿就自动好了。当时不以为然,但是后面每次想用phantomjs
去截图的时候,它都会出现。
首先,我们运行的简单的demo是
var page = require('webpage').create();
page.viewportSize = { width: 1276, height: 800};
var url = 'https://www.baidu.com';
page.open(url, function() {
page.render('text.jpg');
phantom.exit();
});
这是一个最简单的phantomjs的demo,运行command是
$ phantomjs test.js
运行这条命令的时候,偶尔会卡死在那儿;偶尔会报Resource temporarily unavailable的错误。
上stackoverflow上去看,发现这个问题有很多的答案,大致是说进程数太多,超过了系统的限制。
所以这时候我们面临着3个问题
- 1、如何解决进程数太多而不能再fork的问题?
- 2、为什么phantomjs会fork新进程?
- 3、node层有没有什么陷阱导致不断fork?
##一、如何解决进程数太多而不能再fork的问题?
按照so提供的思路,我们用ulimit把max process提高了
$ ulimit -u 50000
然后再次运行demo,发现一点问题都没有了。虽然问题已经解决,但是还是不知道问题在哪儿。
##二、为什么phantomjs会fork进程?
首先,我们看看phantomjs入口文件 /usr/local/lib/node_modules/phantomjs/bin/phantomjs
var binPath = require(path.join(__dirname, '..', 'lib', 'phantomjs')).path
...
var cp = spawn(binPath, args)
我们可以看到,phantomjs其实只是一个壳,它真正spawn了lib/phantomjs.js这个文件。ok,既然是spawn,那就一定会fork出子进程。这会不会是被卡住的真正原因呢?我并没有深入研究…
##三、node层有没有什么陷阱导致不断fork?
如果我们在spawn、fork、或者exec的时候,没有处理好进程的销毁时间,是很有可能出现fork陷阱
的。
另外,宿主进程死掉,被fork出来的进程是不会自动销毁的。
所以,一般来说,我们最好是在spawn的时候做好异常处理;或者用脚本的方式,在杀掉宿主进程的时候,同时也杀掉子进程。