Puppeteerでマルチスレッドが落ちる原因

はじめに

さくらVPSにWebスクレイピング用途でPuppeteerアプリケーションを置いて毎日定時実行していましたが、スクレイピングの関数をマルチで実行すると動いていなかったようだったのでマルチスレッドで起動する方法を調べました。

スクレイピングを関数単位でcronで時刻指定起動していたんですが、時刻がバッティングするとほぼ落ちていました。しかもchromeのプロセスが残ってそれ以降の時刻指定のジョブが動かないという。

自動ツールってめちゃくちゃ便利ですけど、動かない時のダメージがでかいんですよね。。

なお、Puppeteerの基本的な使い方はこちらの記事で紹介しています。

ブラウザ自動操作で楽したいならPuppeteerを使おう
ブラウザ操作の自動化に興味を持ったことはありませんか。仕事のテストだったり、プライベートだったり、どちらにしても定期的にWebサイトで繰り返し同じ操作をするのって面倒なので自動化したいですよねまた、最近のシステムはユーザとのやり取りをW...

1. サーバの性能を確認する

同じ事象が発生している人はまず、サーバの処理性能を確認して見ましょう。

puppeteerってchromeを動かすのでCPUやメモリ消費が大きいです。

さくらVPSの一番安いプラン(615円/月)はメモリ512MB、CPU1Coreなので、これだとシングルで動かさないと無理でした。

MacBook Pro2016だと全然同じ問題が発生しておらず、4多重ぐらいまでなら平気で動きました。

とはいえ、何も気にせず多重化すると再現しそうなため注意が必要です。

性能測定ツール

実際には性能測定ようではないのですが、puppeteer-clusterというpuppeteerを並列で動かせるパッケージがあります。(自分はうまく操作できなかったのですが。。。)

そのパッケージでmonitorというオプションを設定するとその処理で消費している性能が確認できます。Linuxで性能簡単に取れる人はいいですが、手っ取り早く確認したい人にはおすすめです。(MacBookPro2016でシングルスレッドでCPU27.3%、メモリ88.8%です)

f:id:aonion2:20190131234642p:plain
puppeteer-clusterのmonitor機能

4多重あたりからメモリ100%近くなって不安定になります。

f:id:aonion2:20190131235034p:plain
4多重でpuppeteerを実行した時のリソース消費量

インストールはこちらから=>puppeteer-clusterのGithubのページ

puppeteer-clusterを使うためにはコードの関数内で多重処理を記述することができるっぽい。(私はできませんでしたが泣)

ただ、リソース状況がアウトなので、別の対策が必要と思われます。

2. Puppeteerのスクレイピングを同期的に呼び出す(Async/await)

そこで、運用的な回避方法になりますが、1つのWebスクレイピングごとにcronで時刻指定するのではなく、Async/awaitでWebスクレイピングを複数個まとめて同期的に呼び出すことで重複を避けることができました。

具体的なコードは以下の記事で解説しています。

Puppeteerのスクレイピングを同期的に呼び出す(Async/await)
PuppeteerのスクレイピングをAsync/awaitを使って同期的に呼び出す方法です。Async/awaitについて理解できていれば普通に作れると思いますが、慣れていないと難しいと思いますので参考にしてください。(私もハマりました。。...

Async/awaitの基本的な使い方は以下の記事を参照ください。

Node.jsで非同期処理の戻り値を利用する(Async/await)
Node.jsで非同期処理の結果を処理する際にAsync/awaitを利用する方法です。個人的にはcallback関数に比べて直感的に理解しづらかったので慣れない方でも理解しやすいように呼び出し元、呼び出し先(Async関数)のサンプルを用...

結論

そもそもPuppeteerは並列で動かせますが、リソースとの問題が発生します。

リソースが厳しい環境ではコードに工夫が必要になります。

puppeteer-clusterはもう少し触っていきたいです。

コメント

タイトルとURLをコピーしました