環境
サーバ: AWS EC2
PHP7.1
laravel5.1
状況
コンテナを利用したlaravelプロジェクトのスケジューラをホスト側のcronを使って動かしていた
* * * * * docker exec --user www-data php-fpm_container sh -c "php artisan schedule:run" > /dev/null 2>&1
スケジューラ内で1日1回実行されるコマンドが3時間ほどかかるのだが、このコマンド実行中にホスト内のメモリ使用量がどんどん増えていき使用量90%を超える事態に
また、コマンド実行中にphp-fpmのヘルスチェックが失敗するようになっていた
php-fpm:
healthcheck:
test: ["CMD-SHELL","cgi-fcgi -bind -connect localhost:9000 2>&1 || exit 1"]
interval: 1m
timeout: 10s
retries: 3
調査結果
コンテナ内にschedule:runプロセスは残っていないにもかかわらず、ホスト側でcronのプロセスが大量に残っている状態だった(3/1時点で2/28以前の実行プロセスが残っていた
コマンド実行中は、その後に実行されたcronプロセスが全て残り続けるようだった
このcronプロセスが平均0.5%ほどメモリを消費することにより、メモリ使用量が肥大化していた
root 14003 0.0 0.0 183160 2912 ? S Feb28 0:00 \_ /usr/sbin/CROND -n -m off
hoge 14004 0.0 0.0 119852 884 ? Ss Feb28 0:00 | \_ /bin/sh -c docker exec --user www-data php-fpm_container sh -c "php artisan schedule:run" > /d
hoge 14005 0.0 0.4 609184 34388 ? Sl Feb28 0:11 | \_ docker exec --user www-data php-fpm_container sh -c php artisan schedule:run
また、docker eventsコマンドを監視したところ、exec_dieイベント発行が行われずに詰まっている?ようだった
◆ スケジューラ1回目開始 (αコマンド実行)
2022-03-01T15:15:01 container exec_create: sh -c php artisan schedule:run (省略, execID=ff762a994cf8bd1b68b106c85e6fffece2ed9d2c3e626db842ba25dfe38a1393)
2022-03-01T15:15:01 container exec_start: sh -c php artisan schedule:run (省略, execID=ff762a994cf8bd1b68b106c85e6fffece2ed9d2c3e626db842ba25dfe38a1393)
◆ スケジューラ2回目開始
2022-03-01T15:16:01 container exec_create: sh -c php artisan schedule:run (省略, execID=6b6a678463cad21dc30300e6059bc93db27575f4428871b833b4f1a2b4ab3399)
2022-03-01T15:16:01 container exec_start: sh -c php artisan schedule:run (省略, execID=6b6a678463cad21dc30300e6059bc93db27575f4428871b833b4f1a2b4ab3399)
~ スケジューラ2回目の終了が来ない ~
◆ スケジューラ1回目終了
2022-03-01T18:15:01 container exec_die (省略, execID=ff762a994cf8bd1b68b106c85e6fffece2ed9d2c3e626db842ba25dfe38a1393)
◆ すぐにスケジューラ2回目も終了
2022-03-01T18:15:01 container exec_die (省略, execID=6b6a678463cad21dc30300e6059bc93db27575f4428871b833b4f1a2b4ab3399)
解決方法
cronプロセスが残り続ける問題については、デタッチモードで実行することにより結果出力を受け取らずにcronプロセス自体は終了するように変更
* * * * * docker exec -d --user www-data php-fpm_container sh -c "php artisan schedule:run" > /dev/null 2>&1
exec_dieイベント発行の詰まりについては分からずじまいで、php-fpmコンテナのヘルスチェックをnginxコンテナのヘルスチェックに内包することでとりあえずの解決とした