web-dev-qa-db-ja.com

制限chromeヘッドレスCPUおよびメモリ使用量

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 headlessはメモリとCPUを過度に消費しているようです。CPU/メモリの使用量を制限する方法は誰でも知っていますchrome headless?またはいくつかの回避策。

前もって感謝します。

9
Ahmad Hijazi

予測できない[〜#〜] cpu [〜#〜]およびメモリ消費 byChrome Headlessについて多くの議論がありました。 セッション。

議論によると 最小のcpu + mem使用のためにヘッドレスでビルド CPU +メモリ使用量は次の方法で最適化できます:

  • カスタムプロキシまたはC++ ProtocolHandlersを使用して、スタブ1x1ピクセル画像を返すか、完全にブロックすることさえできます。
  • Chromiumチームは、フレームの作成時に programmatic control overの追加に取り組んでいます。現在、ヘッドレスchromeはまだ60 fpsでレンダリングしようとしていますが、これはかなり無駄です。多くのページにはいくつかのフレームが必要です(たぶん10-20 fps)(requestAnimationFrameおよびanimation triggersを使用するため)を適切にレンダリングしますが、ここでは多くのCPUの節約が期待できます。
  • MemoryInfra は、セットアップでメモリを最も消費するコンポーネントを特定するのに役立ちます。
  • 使用方法は次のとおりです。

    $ headless_Shell --remote-debugging-port=9222 --trace-startup=*,disabled-by-default-memory-infra http://www.chromium.org
    
  • Chromiumは常に、利用可能な限りのリソースを使用します。使用率を効果的に制限したい場合は、 cgroups の使用を検討する必要があります。


ここで上記の点を述べたのは、実稼働環境でヘッドレスブラウザーを実行するときに適応する一般的なベストプラクティスの一部です。

resource-usage

図:ヘッドレスクロームの揮発性リソース使用量

  • ヘッドレスブラウザを実行しない

    すべてのアカウントで、可能であれば、ヘッドレスブラウザーを実行しないでください。ヘッドレスブラウザは予測不能で空腹です。ブラウザでできること(JavaScriptの補間と実行のために保存)のほとんどすべては、単純なLinuxツールで実行できます。 HTTPリクエストおよびscrapingifを介してデータを取得するためのエレガントなNode API'sを提供するライブラリがありますそれがあなたの最終目標です。

  • 必要のないときにヘッドレスブラウザを実行しない

    使用していないときでもブラウザを開いたままにしようとするユーザーがいるため、常に接続に使用できます。これはセッションの開始を促進するのに役立つ戦略かもしれませんが、数時間後には悲惨な結果に終わります。これは主に、ブラウザがデータをキャッシュし、ゆっくりとメモリを消費するためです。ブラウザを積極的に使用していないときはいつでも閉じてください!

  • ページではなくブラウザで並列化

    絶対に必要な場合にのみ1つを実行する必要があります。次のベストプラクティスは、各ブラウザーで1つのセッションのみを実行することです。実際には、ページを介して作業を並列化することでオーバーヘッドを節約できますが、1つのページがクラッシュすると、ブラウザー全体がダウンする可能性があります。それに加えて、各ページが完全にクリーンであるとは限りません(Cookieとストレージが流出する可能性があります)。

  • page.waitForNavigation

    観察される最も一般的な問題の1つは、ページの読み込みをトリガーするアクションと、スクリプト実行の突然の損失です。これは、pageloadをトリガーするアクションにより、その後の作業が飲み込まれる可能性があるためです。この問題を回避するには、通常、ページ読み込みアクションを呼び出し、すぐに次のページ読み込みを待つ必要があります。

  • すべてを含めるためにdockerを使用

    Chromeを適切に実行するには、多くの依存関係が必要です。それがすべて完了した後でも、フォントやファントムプロセスなど、気にする必要があるものがあるため、何らかのコンテナを使用してそれを格納することが理想的です。使用可能なリソースの量を制限してサンドボックス化できるため、Dockerはこのタスク用にほとんどカスタムビルドされています。独自のDockerfileを自分で作成します。

    また、ゾンビプロセス(Chromeで一般的に発生する)の実行を避けるために、dumb-initのようなものを使用して適切に起動する必要があります。

  • 2つの異なるランタイム

    2つのJavaScriptランタイムが存在する可能性があります(ノードとブラウザー)。これは共有性の目的には優れていますが、一部のページメソッドでは参照を明示的に渡す必要があるため、混乱を招きます(クロージャーやホイストを使用する場合とは異なります)。

    例として、プロトコルの奥深くでpage.evaluateを使用している間、これは文字通りstringifies関数であり、Chromeに渡すため、クロージャーや巻き上げなどはまったく機能しません。いくつかの参照または値をevaluate呼び出しに渡す必要がある場合、適切に処理される引数としてそれらを単に追加します。

参照: 200万のヘッドレスセッションを実行している観測

12
DebanjanB

Dockerの使用を検討してください。メモリやCPUなどのシステムリソースの使用量をしきい値処理するための機能が十分に文書化されています。幸いなことに、ヘッドレスクローム(X11上)を内部に使用してDockerイメージを構築するのは非常に簡単です。

すぐに使えるソリューションがたくさんありますので、チェックしてみてください: https://hub.docker.com/r/justinribeiro/chrome-headless/

0
Beastmaster