限制镀铬无头CPU和内存使用

时间:2018-06-05 13:51:24

标签: selenium google-chrome headless headless-browser google-chrome-headless

我使用selenium使用以下命令运行chrome headless:

system "LC_ALL=C google-chrome --headless --enable-logging --hide-scrollbars --remote-debugging-port=#{debug_port} --remote-debugging-address=0.0.0.0 --disable-gpu --no-sandbox --ignore-certificate-errors &"

然而,看起来Chrome无头消耗了太多的内存和CPU,有谁知道我们如何限制chrome无头的CPU /内存使用?或者,如果有一些解决方法。

提前致谢。

3 个答案:

答案 0 :(得分:9)

Chrome的无头会话围绕不可预测的 CPU 内存消耗进行了大量讨论。

根据讨论Building headless for minimum cpu+mem usage,可以通过以下方式优化CPU +内存使用率:

  • 使用自定义代理或C ++ ProtocolHandlers,您可以返回存根1x1像素的图像,甚至完全阻止它们。
  • Chromium小组正在努力在制作框架时添加programmatic control。目前无头Chrome仍在尝试以 60 fps 进行渲染,这非常浪费。许多页面的确需要几帧(也许 10-20 fps )才能正确呈现(由于使用了requestAnimationFrameanimation triggers),但是我们期望有很多CPU可以节省的钱。
  • MemoryInfra应该可以帮助您确定哪个组件是设置中最大的内存使用者。
  • 用法可以是:

    $ headless_shell --remote-debugging-port=9222 --trace-startup=*,disabled-by-default-memory-infra http://www.chromium.org
    
  • 铬总是会使用尽可能多的资源。如果要有效限制其利用率,则应考虑使用cgroups


上面提到的几点是在生产环境中运行无头浏览器时要适应的一些常见最佳实践:

resource-usage

图:Headless Chrome的资源浪费情况

  • 不要运行无头浏览器

    对于所有帐户,如果可能的话,请不要运行无头的浏览器。无头浏览器是不可预测的且饥饿的。使用浏览器几乎可以完成的所有工作(用于插值和运行JavaScript的工作)都可以通过简单的Linux工具完成。有些库提供了优雅的Node API,可以通过 HTTP请求抓取(如果您是最终目标)来获取数据。

  • 不需要时不运行无头浏览器

    有些用户试图将浏览器保持打开状态,即使在不使用时也是如此,以便始终可用于连接。尽管这可能是帮助加快会话启动的好策略,但它只会在几个小时后陷入困境。这主要是因为浏览器喜欢缓存内容并缓慢消耗更多的内存。每当您不积极使用浏览器时,请关闭它!

  • 与浏览器而非页面并行

    我们仅在绝对必要时运行一个会话,下一个最佳实践是在每个浏览器中仅运行一个会话。虽然实际上可以通过并行处理页面来节省一些开销,但是如果一个页面崩溃,它可能会导致整个浏览器崩溃。那样,再加上每个页面都不能保证完全干净(cookie和存储可能会泄漏)。

  • page.waitForNavigation

    观察到的最常见问题之一是触发页面加载的操作以及脚本执行的突然丢失。这是因为触发pageload的动作通常会导致后续工作被吞噬。为了解决此问题,通常必须调用page-loading-action,然后立即等待下一个页面加载。

  • 使用docker包含所有内容

    Chrome需要大量依赖才能正常运行。即使所有这些都完成了,您仍然需要担心诸如字体和幻影处理之类的事情,因此使用某种容器来容纳它是理想的。 Docker几乎是为此任务定制的,因为您可以限制可用资源的数量并将其沙箱化。自己创建自己的 Dockerfile

    为避免陷入僵尸进程(通常在Chrome中发生),您需要使用 dumb-init 之类的东西来正确启动。

  • 两个不同的运行时

    可能有两个 JavaScript运行时(Node和浏览器)。这对于共享性而言非常有用,但是却以混淆为代价,因为某些页面方法将要求您显式传递引用(而不是使用闭包或提升)。

    例如,在协议的最底层使用page.evaluate时,实际上是stringifies这个函数并将其传递给Chrome,因此闭包和提升之类的功能根本不起作用。如果您需要将一些引用或值传递到评估调用中,只需将它们附加为可以正确处理的参数即可。

参考:Observations running 2 million headless sessions

答案 1 :(得分:0)

考虑使用Docker。它具有详细记录的功能,可用于限制系统资源(如内存和cpu)的使用。好消息是,构建带有无头Chrome(在X11之上)的Docker映像非常容易。

有很多现成的解决方案,请查看:https://hub.docker.com/r/justinribeiro/chrome-headless/

答案 2 :(得分:0)

我在使用 Centos 7、selenium 和 google-chrome headless 时遇到过这种情况。剩余的 google-chrome 进程留在内存中,并在几个小时内创建了 Out-Of-Memory 链事件。最终我用锤子法解决了这个问题:

/usr/bin/pkill 铬

每小时。通过 crontab。已恢复可用内存。

相关问题