概要
- ある日、seleniumによるフロント画面の正常性確認を行うAWS Lambdaの実行エラーが頻発していることに気づき調査することになりました。
- その際に気づいたseleniumの特性とAWS Lambdaの特性について今回は記事にしていこうと思います。
- もし同じような現象に陥った人がいた時の何らかの助けになれば幸いです。
仕様の確認
- フロント画面の正常性を確認するためにseleniumのwebdriverでヘッドレスモード実行をしていました。
- 実行には、CloudWatchEventを利用し、5分おきにこのLambdaを発火し、実行結果をCloudWatchLogsに吐き出すようになっています。
何が起きたのか
- 一定の間隔でこのseleniumを動かすLambdaが実行中にエラーとなり落ちていました。
- ただ毎回の実行で、このLambdaが落ちるというわけではなくたまに実行エラーとなるのがとても不思議でした。
Lambdaでの実行エラーが発生したときの調査方法
- Lambdaのインサイトメトリクスを有効にするとLambdaのリソースの変化をCloudWatchから追うことができます。
- 今回のようなケースを再現すると下記のようなエラーの間隔とメモリ、CPUの使用率を示します。
原因とLambdaとSeleniumの特性
- 今回の原因は、実はLambdaとSeleniumの特性が非常に良く現れた現象と言えます。
- 実は、AWS Lambdaは、ある短期間で実行されると前回の実行環境を再利用するという特徴があります。
※ 詳しくは以下の記事を参照ください。
- 今回、メモリが徐々に上昇し、メモリがサチるとリセットされるという動作は、再利用されたコンテナ内でメモリ不足が発生すると、Lambdaが自動的にコンテナの再作成を行う為です。
では、なぜ再利用されたコンテナ内でメモリが急上昇したのか?
- それは、Seleniumの特性にあります。
- 実は今回の実装コード内でSeleniumで利用しているwebdriverのプロセスをきちんと切っていないため、毎回の実行で同一コンテナ内でプロセスを作成し、テストをしていることで前のプロセスが残りメモリを食い潰したというのが原因になります。
Seleniumの実行を終了させるメソッド
-
driver.close(): アクティブになっているタブを終了
ただ、「driver.close()」だけだとプロセスが残り続ける可能性があります。 -
driver.quit(): すべてのタブを閉じてブラウザを終了
「quit()」でプロセスを完全に終了させることができます。
=> なので、Seleniumの実装ではテストが完了しSeleniumを終了させる場合は、driver.quit():を使うのが良いでしょう。
- 今回のエラーについても、driver.close():からdriver.quit():に変更したことでLambdaの実行エラーがなくなりました。
まとめ
- もしLambdaを使用し同じような現象に陥っていた場合は、一度Lambdaのインサイトメトリクスを有効化しリソースがどう使われているのかを確認するとよいでしょう。
参考