はじめに
スクレイピングを実施するnode.jsサーバをforeverで稼働させていたのですが、どうもforeverの再起動時にブラウザが終了されず、Chromeのプロセスが残っていました。
forever再起動時に、稼働中のブラウザは終了して新規作成されるのが嬉しいです。ブラウザを終了させる方法を模索したのでメモ。
対応方法
node.js側で終了のシグナルを受け取った際に、ブラウザを終了してからnode.jsのプログラムを終了する流れにすることによって解決します。
forever終了時のシグナルをSIGTERMに変更
foreverが、プロセスを終了させるために送るシグナルのデフォルトはSIGKILL
です。
node.jsでは、シグナルを受け取った時にイベントを発行できますが、SIGKILL
は不可なので、送るシグナルをSIGTERM
に変更します。
foreverで起動するときのオプションで、終了時にプロセスに送るシグナルを変更することができます。
forever start --killSignal=SIGTERM xxxx.js
puppeteer起動時オプション変更
puppeteerは、SIGTERMのシグナルが送られてくるとブラウザを閉じてくれます…が、その後プログラムを終了してくれません。
終了してくれないと困るので、puppeteer側のSIGTERMシグナル受信時の処理を無効にして、ブラウザを閉じる処理は自分で書くことにしました。
SIGTERMシグナル受信時の処理を実施するかどうかはブラウザ起動時のオプションで指定可能です。
const launchOption={handleSIGTERM: false};
browser = await puppeteer.launch(launchOption);
SIGTERMシグナル受信時のイベントをリスナーに登録
最後に、SIGTERMのシグナルが送られてきたら、「ブラウザを終了させてからプログラムを終了する」処理をリスナーに登録すれば完了です。
process.on('SIGTERM', async () => {
console.log('Got SIGTERM. close browser.');
await browser.close();
process.exit(0);
});
これで再起動するたびにゾンビChromeが増える事態は無くなります。