我可以为每个CPU创建更多PhantomJS 进程,或者同时为每个幻像进程创建多个网页实例吗?
例如,1:1:1表示:1个4 CPU ,我生成4个PhantomJS 进程,并创建1个网页在每个过程中同时进行。
这是并发的限制。
有没有一种好方法可以证明我可以改变1:1:1的比例以及哪个比例是好的?
如果幻像:页面的比例是1:n,是否会出现上下文切换竞争条件,这会导致PhantomJS错误吗?
答案 0 :(得分:0)
没有三通比率这样的东西。比例恰好有两方。现在我们已经解决了这个问题,让我们分开比率。
我们可以使用x个可用线程(CPU /核心)和y个PhantomJS进程来定义x:y。然后我们可以用z个page
个实例来定义y:z。
只要硬件支持它(主要是RAM),您就可以运行任意数量的PhantomJS进程。但对于大多数架构(全部?),y/x
时相对性能(y > x
)会下降。如果您有许多进程而没有多少内核,则至少有两个进程必须共享一个核心(如果您有多线程,则必须共享一个核心)。所以这两个过程不会像其他过程一样快。这与PhantomJS无关,而是正常的多进程行为。
如果您有y >> x
,那么即使上下文切换流程也可能成为瓶颈,一切都会非常缓慢。
总是希望只生成与核心/线程一样多的进程(可能更少)。
对于几乎所有情况,PhantomJS进程默认独立运行。只有当他们运行的页面使用localStorage时,您才会遇到问题。 localStorage始终保留在磁盘上,无法更改。
page
个实例PhantomJS运行JavaScript脚本。由于JavaScript作为一个整体是单线程的,因此无法进行任何并行处理,但您可以通过正常的JavaScript事件循环获得并发。
PhantomJS支持每个进程多个page
个实例,而且效果相当不错,但当然因为JavaScript是单线程的,所以多个页面的执行是隔行扫描的。这意味着在“同一时间”打开两页应该会或多或少地导致一个接一个地打开它们。
严格来说并非如此,因为等待一个页面的资源可以让其他页面进行进一步处理。当按顺序打开页面时,其他页面不能使用一页等待加载资源的时间。
另一方面,在一个进程中不能使用大量page
个实例,因为不同页面的请求会相互阻碍。 HTTP请求在TCP上运行。如果存在多个争用带宽的TCP,则连接的整体效率较低。但这应该比顺序情况更快。这就是为什么HTTP / 2(SPDY)是个好主意。
并发处理比顺序处理更快,但是每个PhantomJS进程(甚至可能针对多个进程)编程管理多个page
实例的程序更难。
page
实例此脚本显示两个版本的请求网站。第一次迭代的结果差异很大,因为缓存尚未填充。以后无法清除缓存,因此每次迭代都会在第一次迭代后使用缓存资源。
var urls = [
'https://google.com',
'http://stackoverflow.com/contact',
'http://stackoverflow.com/questions?pagesize=15&sort=newest',
'http://www.spiegel.de/'
];
function sequential(callback) {
var copiedUrls = JSON.parse(JSON.stringify(urls)),
page = require('webpage').create(),
start = (new Date()).getTime();
function sequentialHelper(){
//console.log("seqHelp " + copiedUrls.length);
if (copiedUrls.length == 0) {
start = (new Date()).getTime() - start;
page.close();
callback(start);
return;
}
page.open(copiedUrls.shift(), function(s){
sequentialHelper();
});
}
sequentialHelper();
}
function parallel(callback) {
var copiedUrls = JSON.parse(JSON.stringify(urls)),
max = copiedUrls.length,
pages = [],
start;
function checkFin(){
max--;
//console.log("parCheck " + max);
if (0 === max) {
start = (new Date()).getTime() - start;
pages.forEach(function(page){
page.close();
});
callback(start);
}
}
start = (new Date()).getTime();
copiedUrls.forEach(function(url){
var page = require('webpage').create();
pages.push(page);
page.open(url, function(s){
checkFin();
});
});
}
var repeat = 5,
current = 0,
times = [];
function repeater(){
if (current === repeat) {
console.log(JSON.stringify(times, undefined, 4));
phantom.exit();
}
console.log("repeated: " + (current+1));
var t = {
par: (new Date()).getTime()
};
parallel(function(innerTime){
t.par = (new Date()).getTime() - t.par;
t.pari = innerTime;
t.seq = (new Date()).getTime();
sequential(function(innerTime){
t.seq = (new Date()).getTime() - t.seq;
t.seqi = innerTime;
times.push(t);
repeater();
});
});
current++;
}
repeater();
输出:
[
{
"par": 10653,
"pari": 10652,
"seq": 5304,
"seqi": 5301
},
{
"par": 2936,
"pari": 2936,
"seq": 5224,
"seqi": 5219
},
{
"par": 3167,
"pari": 3167,
"seq": 4478,
"seqi": 4474
},
{
"par": 2506,
"pari": 2506,
"seq": 6868,
"seqi": 6862
},
{
"par": 2479,
"pari": 2479,
"seq": 3753,
"seqi": 3749
}
]