Aws lambda AWS Lambda上的傀儡机目标闭合错误
我有一个Lambda函数,它从SQS队列中读取邮政编码,并尝试从包含地图的网页中获取网络可用性信息。为此,Lambda函数截取图像响应并计算每种颜色的像素数(对应于网络可用性类型) 我面临的问题是,如果我在本地计算机上测试它,或者在Lambda上运行一个测试,它就可以正常工作。当我刚开始向SQS发送消息时,它也可以正常工作,但是当SQS队列中已经有一些消息并且Lambda并行运行时,几乎100%的执行失败,出现目标关闭错误或会话关闭错误。当木偶演员试图对页面执行某个操作,但页面已经关闭时,似乎会发生此错误。大多数情况下,此错误发生在页面加载之后/期间或等待第一个选择器之前/期间。有一些建议认为页面可能会由于内存/cpu限制而崩溃,我尝试将Puppeter内存增加到2Gb,将Lambda内存限制增加到2.5Gb,我认为这对于单个页面来说应该足够了,但它仍然会崩溃。有趣的是,如果我只在它成功后运行它 此外,我还检测到几次“EventEmitter内存泄漏”。11个退出侦听器添加了“erorr”,并尝试添加行Aws lambda AWS Lambda上的傀儡机目标闭合错误,aws-lambda,puppeteer,Aws Lambda,Puppeteer,我有一个Lambda函数,它从SQS队列中读取邮政编码,并尝试从包含地图的网页中获取网络可用性信息。为此,Lambda函数截取图像响应并计算每种颜色的像素数(对应于网络可用性类型) 我面临的问题是,如果我在本地计算机上测试它,或者在Lambda上运行一个测试,它就可以正常工作。当我刚开始向SQS发送消息时,它也可以正常工作,但是当SQS队列中已经有一些消息并且Lambda并行运行时,几乎100%的执行失败,出现目标关闭错误或会话关闭错误。当木偶演员试图对页面执行某个操作,但页面已经关闭时,似乎会
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)”中,
“在执行上下文中