кукловод / хром: обрабатывать сбойные страницы с тяжелой памятью?

У меня такой код:

puppeteer.launch().then(async browser => {
    for (let id of ids) {
        try {
            const page = await browser.newPage();
            //const url = 'chrome://crash';
            await page.goto(url + id)
            await page.waitFor(5000);
            await page.screenshot({
                path: path.join(__dirname, "../public/images/screenshots/" + id + ".png"),
                clip: { x: 10, y: 70, width: 780, height: 470}
            });
        } catch (error) {
            console.log('Exception', id, error.message);
            page.close();
        }
    };
    browser.close();
});

Обычно он работает нормально, но у меня проблемы с определенной страницей (с URL-адресом, которым, к сожалению, я не могу поделиться).

Эта страница пытается загрузить ГБ данных и приводит к сбою Chrome, поэтому я предполагаю, что это также вызывает сбой Chromium.

Ошибка, которую я вижу на этой странице: Exception 6766 Navigation Timeout Exceeded: 30000ms exceeded. Это нормально, но, похоже, на этом не заканчивается - из-за этого весь мой сервер зависает, я думаю, потому что он пытается использовать слишком много памяти на уровне ОС.

Как я могу предотвратить зависание моего сервера и правильно с этим справиться? Могу ли я предоставить Chromium флаги для ограничения используемой памяти и постепенного отказа? Я также не уверен, что моя обработка ошибок в целом правильная, поэтому любые советы будут оценены.


person Richard    schedule 17.01.2018    source источник
comment
Я думаю, что, вероятно, лучше всего отделить фактический браузер от вашей инфраструктуры, чтобы сбой его не разрушал весь ваш стек. Я создатель браузера без браузера (browserless.io), и его цель - сделать именно это. Здесь также доступны сборки докеров с открытым исходным кодом: github.com/joelgriffith/browserless   -  person browserless    schedule 18.01.2018


Ответы (2)


несколько идей:

Во-первых, это может не быть связано с вашей первоначальной проблемой, но позволит сэкономить память. Вы открываете много вкладок (страниц), не закрывая их, что может занять много памяти, если ваш список идентификаторов длинный.

Попробуйте перебрать идентификаторы, загрузив новый URL вместо создания новых страниц.

Также вы можете продлить тайм-аут, чтобы проверить, поможет ли больше времени.

Есть хромовые флажки, которые вы можете передать при запуске кукольника. Вот полный список переключателей Chromium.

Вы можете попробовать: --unlimited-storage или --force-gpu-mem-available-mb.

Также это может пригодиться для отладки: --full-memory-crash-report

Вы можете искать там все другие флаги, связанные с памятью.

Вот как вы можете передать флаги кукловоду и другие предложения, о которых я упоминал:

puppeteer.launch({args: ['--unlimited-storage', '--full-memory-crash-report']}).then(async browser => {
  const page = await browser.newPage();

  for (let id of ids) {
      try {
          //const url = 'chrome://crash';
          // Timeout will be 2 min and will wait till network is idle before taking the screenshot
          await page.goto(url + id, {timeout: 120000, waitUntil: 'networkidle0'}); 
          await page.screenshot();
      } catch (error) {
          console.log('Exception', id, error.message);
          // If you catch an error you should throw it and handle it on the parent function
          // or set up an event listener so you can now what's the state of your app
          throw new Err (error);

          // Since we are only opening one page and browsing from here
          // no need to close when you encounter an error
          // just goto the next iteration
          // page.close();
      }
  };
  browser.close();
});
person EcoVirtual    schedule 17.01.2018

Попробуйте передать параметр запуска {args: ['--disable-dev-shm-usage']} команде launch() - это предполагается улучшить способность Puppeteer отображать большие / сложные страницы.

person mjs    schedule 18.01.2018
comment
Спасибо! На самом деле я не работаю внутри контейнера докеров - только на Ubuntu. Так это, наверное, не имеет значения? - person Richard; 29.01.2018
comment
@Richard Да, правда, это, вероятно, поможет, только если вы используете Docker. - person mjs; 31.01.2018