Aws lambda AWS Lambda上的傀儡机目标闭合错误

Aws lambda AWS Lambda上的傀儡机目标闭合错误,aws-lambda,puppeteer,Aws Lambda,Puppeteer,我有一个Lambda函数,它从SQS队列中读取邮政编码,并尝试从包含地图的网页中获取网络可用性信息。为此,Lambda函数截取图像响应并计算每种颜色的像素数(对应于网络可用性类型) 我面临的问题是,如果我在本地计算机上测试它,或者在Lambda上运行一个测试,它就可以正常工作。当我刚开始向SQS发送消息时,它也可以正常工作,但是当SQS队列中已经有一些消息并且Lambda并行运行时,几乎100%的执行失败,出现目标关闭错误或会话关闭错误。当木偶演员试图对页面执行某个操作,但页面已经关闭时,似乎会

我有一个Lambda函数,它从SQS队列中读取邮政编码,并尝试从包含地图的网页中获取网络可用性信息。为此,Lambda函数截取图像响应并计算每种颜色的像素数(对应于网络可用性类型)

我面临的问题是,如果我在本地计算机上测试它,或者在Lambda上运行一个测试,它就可以正常工作。当我刚开始向SQS发送消息时,它也可以正常工作,但是当SQS队列中已经有一些消息并且Lambda并行运行时,几乎100%的执行失败,出现目标关闭错误或会话关闭错误。当木偶演员试图对页面执行某个操作,但页面已经关闭时,似乎会发生此错误。大多数情况下,此错误发生在页面加载之后/期间或等待第一个选择器之前/期间。有一些建议认为页面可能会由于内存/cpu限制而崩溃,我尝试将Puppeter内存增加到2Gb,将Lambda内存限制增加到2.5Gb,我认为这对于单个页面来说应该足够了,但它仍然会崩溃。有趣的是,如果我只在它成功后运行它

此外,我还检测到几次“EventEmitter内存泄漏”。11个退出侦听器添加了“erorr”,并尝试添加行
process.setMaxListeners(0),但没有帮助

Lambda代码:

const chromium = require('chrome-aws-lambda');
const PNG = require('pngjs').PNG;
const Promise = require('bluebird');

function groupByFour(arr) {
    const result = [];
    const len = Math.floor(arr.length / 4);

    for (let i = 0; i < len; i++) {
        result.push(arr.slice(4 * i, 4 * (i + 1)));
    }

    return result;
}

function addImageToGroupStats(hex, allUniques, num, group) {
    const arr = hex.match(/../g);
    // Pixel format R G B A
    const groupedArr = groupByFour(arr);
    const uniques = {};
    groupedArr.forEach(group => {
        const key = group.join('');
        uniques[key] = (uniques[key] || 0) + 1;
        allUniques[key] = (allUniques[key] || 0) + 1;
    })
    console.log(num, group, uniques);
}

exports.handler = main = async (event, context) => {
    process.setMaxListeners(0);
    const { messageId, body } =  event.Records[0];
    console.log('SQS message %s: %j', messageId, body);
    const postcode = body.padStart(5, '0');

    let lastImageFoundTs = null; // to wait for image loading
    let waitForImagesStarted = null; // to reject after 15 sec
    let startTrackingPics = false; // to avoid tracking initial images
    let imageCount = 0; // total images count
    const allUniques4G = {}; // number of pixels of each color for all images

    // Images urls for 4G/LTE Map
    const lteImageUrls = [];

    function waitForImages() {
        return new Promise( (resolve, reject) => {
            const timer = setInterval(function() {
                if (lastImageFoundTs && Date.now() - lastImageFoundTs > 2500) {
                    clearInterval(timer);
                    return resolve();
                }
                if (!waitForImagesStarted) {
                    waitForImagesStarted = Date.now();
                }
                if (Date.now() - waitForImagesStarted > 15000) {
                    clearInterval(timer);
                    return reject(`${postcode}: waited for images more than 15 sec`);
                }
            }, 500);
            
        });
    }

    const browser = await chromium.puppeteer.launch({
        executablePath: await chromium.executablePath,
        args: [...chromium.args, "--shm-size=2gb"],
        defaultViewport: chromium.defaultViewport,
        headless: chromium.headless,
        devtools: true,
        slowMo: 250
    });
    
    const page = await browser.newPage();

    await page.setRequestInterception(true);

    page.on('request', function(request) {
        request.continue();
    });

    page.on('response', async function(response) {
        try {
            if (/4GDataCoverage\/MapServer\/tile/i.test(response.url()) && startTrackingPics) {
                if (response.ok) {
                    imageCount++;
                    let num = imageCount;
                    lteImageUrls.push(response.url());
                    lastImageFoundTs = Date.now();

                    const buff = await response.buffer();
                    lastImageFoundTs = Date.now();
                    const png = PNG.sync.read(buff);
                    // Pixels array
                    const hex = png.data.toString('hex');
                    addImageToGroupStats(hex, allUniques4G, num, '4GDataCoverage');
                }
            }
        } catch(e) {
            console.log(postcode, '4GDataCoverage Callback error:', e.message);
        }
        
    });

    await page.setViewport({ width: 1366, height: 768 });
    await page.goto('https://www.verizonwireless.com/reusable-content/landing-page/coverage-map.html', {waitUntil: 'load', timeout: 0});
    await page.waitFor('#searchbox input');
    await page.type('#searchbox input', postcode);
    startTrackingPics = true;
    await page.click('#btn-submit-usearch');
    await waitForImages();
    console.log(`Pixels of all 4GDataCoverage images`, allUniques4G);
    try {
        await browser.close();
    } catch(e) {
        console.log('Error:', e.message);
    }
    return allUniques4G;

}
const chromium=require('chrome-aws-lambda');
const PNG=require('pngjs').PNG;
const Promise=require(‘蓝鸟’);
函数groupByFour(arr){
常量结果=[];
const len=数学楼层(arr.length/4);
for(设i=0;i{
const key=group.join(“”);
uniques[key]=(uniques[key]| | 0)+1;
allUniques[键]=(allUniques[键]| | 0)+1;
})
console.log(num、group、uniques);
}
exports.handler=main=async(事件、上下文)=>{
process.setMaxListeners(0);
const{messageId,body}=event.Records[0];
console.log('SQS消息%s:%j',消息ID,正文);
const postcode=body.padStart(5,'0');
让LastImageFounds=null;//等待图像加载
让waitForImagesStarted=null;//在15秒后拒绝
让startTrackingPics=false;//避免跟踪初始图像
让imageCount=0;//图像总数
const allUniques4G={};//所有图像每种颜色的像素数
//4G/LTE地图的图像URL
常量LTIMAGEURLs=[];
函数waitForImages(){
返回新承诺((解决、拒绝)=>{
常量计时器=设置间隔(函数(){
如果(LastImageFounds&&Date.now()-LastImageFounds>2500){
清除间隔(计时器);
返回resolve();
}
如果(!waitForImagesStarted){
waitForImagesStarted=Date.now();
}
如果(Date.now()-waitForImagesStarted>15000){
清除间隔(计时器);
返回拒绝(`${postcode}:等待图像超过15秒`);
}
}, 500);
});
}
const browser=等待chromium.puppeter.launch({
可执行路径:等待chromium.executablePath,
args:[…chromium.args,“--shm大小=2gb”],
defaultViewport:chromium.defaultViewport,
无头:铬,无头,
devtools:没错,
slowMo:250
});
const page=wait browser.newPage();
等待页面。setRequestInterception(true);
第页('request',函数(request){
请求。继续();
});
第页('response',异步函数(response){
试一试{
if(/4GDataCoverage\/MapServer\/tile/i.test(response.url())和&startTrackingPics){
if(response.ok){
imageCount++;
设num=imageCount;
lteimageURL.push(response.url());
lastImageFoundTs=Date.now();
const buff=wait response.buffer();
lastImageFoundTs=Date.now();
constpng=png.sync.read(buff);
//像素阵列
const hex=png.data.toString('hex');
addImageToGroupStats(十六进制,allUniques4G,num,'4GDataCoverage');
}
}
}捕获(e){
log(邮政编码“4GDataCoverage回调错误:”,e.message);
}
});
等待page.setViewport({宽度:1366,高度:768});
等待页面。转到('https://www.verizonwireless.com/reusable-content/landing-page/coverage-map.html“,{waitUntil:'load',超时:0});
wait page.waitFor(“#搜索框输入”);
等待页面。键入(“#搜索框输入”,邮政编码);
startTrackingPics=真;
等待页面。单击(“#btn提交使用搜索”);
等待waitForImages();
log(`所有4GDataCoverage图像的像素',allUniques4G);
试一试{
等待浏览器关闭();
}捕获(e){
console.log('Error:',e.message);
}
归还诱惑物4g;
}
错误示例:

{
    "errorType": "Error",
    "errorMessage": "Protocol error (DOM.resolveNode): Target closed.",
    "message": "Protocol error (DOM.resolveNode): Target closed.",
    "stack": [
        "Error: Protocol error (DOM.resolveNode): Target closed.",
        "    at /var/task/node_modules/puppeteer-core/lib/Connection.js:183:56",
        "    at new Promise (<anonymous>)",
        "    at CDPSession.send (/var/task/node_modules/puppeteer-core/lib/Connection.js:182:12)",
        "    at ExecutionContext._adoptBackendNodeId (/var/task/node_modules/puppeteer-core/lib/ExecutionContext.js:190:41)",
        "    at ExecutionContext._adoptElementHandle (/var/task/node_modules/puppeteer-core/lib/ExecutionContext.js:207:17)",
        "    at async Frame.waitForSelector (/var/task/node_modules/puppeteer-core/lib/FrameManager.js:631:20)",
        "    at async Runtime.main [as handler] (/var/task/index.js:170:5)",
        "  -- ASYNC --",
        "    at Frame.<anonymous> (/var/task/node_modules/puppeteer-core/lib/helper.js:111:15)",
        "    at Frame.waitFor (/var/task/node_modules/puppeteer-core/lib/FrameManager.js:612:19)",
        "    at Page.waitFor (/var/task/node_modules/puppeteer-core/lib/Page.js:1113:29)",
        "    at Runtime.main [as handler] (/var/task/index.js:170:16)",
        "    at runMicrotasks (<anonymous>)",
        "    at runNextTicks (internal/process/task_queues.js:62:5)",
        "    at listOnTimeout (internal/timers.js:518:9)",
        "    at processTimers (internal/timers.js:492:7)"
    ]
}
{
“errorType”:“Error”,
“errorMessage”:“协议错误(DOM.resolveNode):目标已关闭。”,
“消息”:“协议错误(DOM.resolveNode):目标已关闭。”,
“堆栈”:[
“错误:协议错误(DOM.resolveNode):目标已关闭。”,
“at/var/task/node_modules/puppeter core/lib/Connection.js:183:56”,
“新承诺()”,
“在CDPSession.send(/var/task/node_modules/puppeter core/lib/Connection.js:182:12)”中,
“在执行上下文中