Puppeteer 阻塞事件循环

Lij*_*ose 5 node.js puppeteer

  • 傀儡师版本:1.1.0
  • 平台/操作系统版本:Ubuntu 16.04.6 LTS
  • Node.js 版本:v8.17.0
const express = require('express');
const blocked = require('blocked-at')
const app = express();
const PORT = 3000;
const URL = "https://www.huffingtonpost.in/entry/india-drops-10-spots-democracy-index_in_5e27ebc3c5b67d8874a92ab1"
let browser;

app.get('execute', async  (req, res) =>{
    page = await browser.newPage();
    await page.goto(URL, {
        waitUntil: 'networkidle0',
        timeout: 3000000
    })
});

app.listen(PORT, async () => {
    browser = await puppeteer.launch(CHROME_LAUNCHER_OPTIONS);
    return;
})

blocked((time, stack, {type, resource}) => {
 console.log(`Blocked for ${time}ms, operation started here:`, stack,"TYPE :",type)
}, {resourcesCap: 100})
Run Code Online (Sandbox Code Playgroud)

我们有一个快速服务器,它将创建一个浏览器实例。当请求进来时,我们正在创建和渲染页面以获取页面的内容。

预期的结果是什么?我希望并行处理请求

#!/bin/bash
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
curl --location --request GET 'http://localhost:3000/execute' &
wait
Run Code Online (Sandbox Code Playgroud)

会发生什么? 由于某些 WebSocket 连接,请求似乎被阻止了。在此处输入图片说明

小智 0

您看到的阻止事件循环的 websocket 相关函数是 CDP(Chrome 调试器协议)流量。这就是 puppeteer 与无头浏览器通信的方式。除了将其从主线程中删除之外,您对此无能为力。

我正在使用Piscina来运行工作人员池。它非常简单,只为我的项目添加了大约 12 个 LOC。需要注意的一件事:使用初始化函数创建浏览器实例 ( ),有关详细信息,puppeteer.launch()请参阅 Piscina github 自述文件延迟工作人员的可用性部分。否则,工作线程可能会在开始工作之前设置为就绪。

puppeteer.launch()根据看起来很精通的人的这篇文章,每个线程使用一个浏览器实例(在每个工作线程中调用) 。他们建议:

与浏览器并行,而不是与页面并行

我正在使用这种方法编写公开 JSON API 的 HTML 到 PDF 转换服务。到目前为止,没有阻塞具有预期负载的事件循环。我正在尝试工作线程数与 CPU 核心的理想比率。大多数时间都花在等待外部 CSS 请求完成上。