puppeteer-cluster:队列而不是执行

puppeteer-cluster: queue instead of execute

我正在试验 Puppeteer Cluster,但我只是不明白如何正确使用队列。它只能用于您不等待响应的呼叫吗?我正在使用 Artillery 同时发出一堆请求,但它们都失败了,而当我直接执行命令时只有一些失败。

我直接从 examples 中提取了代码,并将 execute 替换为 queue,我希望它能正常工作,只是代码不等待结果。有没有办法实现这一目标?

所以这有效:

const screen = await cluster.execute(req.query.url);

但这会中断:

const screen = await cluster.queue(req.query.url);

这是 queue 的完整示例:

const express = require('express');
const app = express();
const { Cluster } = require('puppeteer-cluster');

(async () => {
    const cluster = await Cluster.launch({
        concurrency: Cluster.CONCURRENCY_CONTEXT,
        maxConcurrency: 2,
    });
    await cluster.task(async ({ page, data: url }) => {
        // make a screenshot
        await page.goto('http://' + url);
        const screen = await page.screenshot();
        return screen;
    });

    // setup server
    app.get('/', async function (req, res) {
        if (!req.query.url) {
            return res.end('Please specify url like this: ?url=example.com');
        }
        try {
            const screen = await cluster.queue(req.query.url);

            // respond with image
            res.writeHead(200, {
                'Content-Type': 'image/jpg',
                'Content-Length': screen.length //variable is undefined here
            });
            res.end(screen);
        } catch (err) {
            // catch error
            res.end('Error: ' + err.message);
        }
    });

    app.listen(3000, function () {
        console.log('Screenshot server listening on port 3000.');
    });
})();

我在这里做错了什么?我真的很想使用排队,因为没有它,每个传入的请求似乎都会减慢所有其他请求的速度。

puppeteer-cluster 的作者在这里。

引自文档:

cluster.queue(..): [...] Be aware that this function only returns a Promise for backward compatibility reasons. This function does not run asynchronously and will immediately return.

cluster.execute(...): [...] Works like Cluster.queue, just that this function returns a Promise which will be resolved after the task is executed. In case an error happens during the execution, this function will reject the Promise with the thrown error. There will be no "taskerror" event fired.

何时使用哪个函数:

  • 如果要对大量作业(例如 URL 列表)进行排队,请使用 cluster.queue。任务函数需要通过将结果打印到控制台或将它们存储到数据库中来负责存储结果。
  • 如果您的任务函数 returns 结果,请使用 cluster.execute。这仍然会将作业排队,所以这就像除了等待作业完成之外还调用 queue。在这种情况下,最常见的是 "idling cluster" 存在,当请求到达服务器时使用(就像在您的示例代码中一样)。

所以,您肯定要使用cluster.execute,因为您要等待任务功能的结果。您没有看到任何错误的原因是(如上所述)cluster.queue 函数的错误是通过 taskerror 事件发出的。 cluster.execute 错误直接抛出(Promise 被拒绝)。最有可能的是,在这两种情况下,您的工作都会失败,但它仅对 cluster.execute

可见