phantomjs是一个headless浏览器。

因为它自带page,webserver模块,一开始我误以为它是类似浏览器的一个东西;实际上比作node更为合适:它是单线程的。

场景:

phantomjs内部有一个待渲染page,外部通过webserver与之交互。

问题:

  1. 内部的page可能出错、超时,导致渲染失败

  2. 因为是以server运行,不会自己关闭。

现有机制是加了一个心跳包,让其自己超时关闭。但是这个方案有一个非常大的问题:phantomjs是单线程的,当page出错,导致死循环,它自己不能再执行其他任务了。

查阅api,发现phantomjs还带了一个有趣的功能:开子进程

遂如下实验:

开启:

../phantomjs process.js 2333 1

参数为:1. port;2. 是否是父进程,如不是,则初始化内部一个page(有一个10s while)。

测试:

~curl'127.0.0.1:2333?tell&spawn=2222'
2222
~curl'127.0.0.1:2333?tell&spawn=2223'
2222,2223
~curl'127.0.0.1:2333?tell&kill=2222&spawn=2224'
2223,2224
~curl'127.0.0.1:2333?tell&kill=2223'
2224
~curl'127.0.0.1:2333?tell&kill=2224'

返回值为现在运行的子进程port。

注意,初始化时每个都有10s死循环,但是以上命令可以连续执行。所以,由一个phantomjs作为manager原理是可行的。

并且如果一个子进程被kill或退出,也会有exit事件返回到parent。

总结:

这样我们可能的方案:

  1. 由manager管理心跳,超时主动kill
  2. 定时重启子进程

但是因为phantomjs本身不太稳定,长时间运行的稳定性值得怀疑。最简单的方案可能反而是直接定时重启。