apache2をstopしたら、処理中のリクエストスレッドは中断?処理が終わるまで待つ?

リクエスト処理中にapache2をstopしたら、そのリクエストスレッドは途中で中断するのでしょうか?リクエストスレッドの処理が終わるのを待つのでしょうか?

結果

停止コマンドリクエストスレッドの結果
sudo systemctl stop apache2途中で中断
sudo apachectl stop途中で中断
sudo apachectl graceful-stop処理完了を待つ、ただし新しいリクエストは拒否

AWS Beastalkのデプロイやオートスケール縮小でインスタンス削除しますが、このときのapache2の停止方法がstopなのかgraceful-stopなのかがわかりませんでした。

インスタンス削除するとき、処理中のスレッドは中断されるのでしょうか、処理が終わるのを待ってから、インスタンス削除するのでしょうか?

それを調べるための下調べです。

なぜ、こんなことを調べたいのかといいますと、

リクエストスレッドの処理で、MySQLへのDBアクセスしかしていないなら、トランザクション開始しておくことで、スレッドが中断してしまっても不正なデータが保存されることはありません。

ところが最近は、外部サービスのAPIと連携することも多いです。

APIレスポンスを待ってDB保存まで完了できるのなら、あまり心配はありません。

しかし、APIレスポンスを待っている途中で中断してしまったら、外部サービスの状態とこちらの状態が不整合になってしまうことがあります。結果整合性を保てるようにシステムや処理を組み立てる必要があります。

実験準備

/var/www/html/longprocess.php を用意します。

処理内容は、

  1. /var/www/html/log.txtに日時を記録
  2. 20秒待つ
  3. /var/www/html/log.txtに日時を記録

ブラウザに表示するだけでいいと思うけど、log.txtへの保存は必要なの?

ブラウザとの接続は切断しても、リクエストスレッド処理は継続しているかもしれないことを考えたのね

#1<br> <?php $i = $_GET['i']; $fp = fopen("/var/www/html/log.txt", "a"); fputs($fp, "i=$i\n"); fputs($fp, "i=$i " . strftime('%H:%M:%S') . "\n"); fclose($fp); $time = time(); while (time() < $time + 20) { $x = sin(time()); } $fp = fopen("/var/www/html/log.txt", "a"); fputs($fp, "i=$i " . strftime('%H:%M:%S') . "\n"); fclose($fp); ?> #9<br>
Code language: HTML, XML (xml)

ターミナル1

log.txtを新規作成して、chmod 666 しておきます。log.txtをtail -f で監視します。

$ cd /var/www/html $ sudo touch log.txt $ sudo chmod 666 log.txt $ tail -f log.txt
Code language: JavaScript (javascript)

ターミナル2

apache2を起動します。

$ sudo systemctl start apache2

ブラウザ1

http://localhost/longprocess.php?i=1 にアクセスします。ブラウザ上には、約20秒かかって、

#1 #9
Code language: CSS (css)

と表示されます。

ターミナル1には、次のような表示がされます。

i=1 i=1 17:59:37 i=1 17:59:57

実験1 systemctl stop apache2

ターミナル2

apache2を起動します。

$ sudo systemctl start apache2

ブラウザ1

http://localhost/longprocess.php?i=1 にアクセスします。

ターミナル1

すぐに表示されます。

i=1 i=1 18:21:22

ターミナル2

apache2を停止します。

$ sudo systemctl stop apache2

ターミナル1

20秒待っても、さきほどの表示から変化はありません。20秒間の処理の途中で、中断してしまいました。

i=1 i=1 18:21:22

実験2 apachectl stop

ターミナル2

apache2を起動します。

$ sudo systemctl start apache2

ブラウザ1

http://localhost/longprocess.php?i=1 にアクセスします。

ターミナル1

すぐに表示されます。

i=1 i=1 18:24:44

ターミナル2

apache2を停止します。

$ sudo apachectl stop

ターミナル1

20秒待っても、さきほどの表示から変化はありません。20秒間の処理の途中で、中断してしまいました。

i=1 i=1 18:24:44

実験3 apachectl graceful-stop

ターミナル2

apache2を起動します。

$ sudo systemctl start apache2

ブラウザ1

http://localhost/longprocess.php?i=1 にアクセスします。

ターミナル1

すぐに表示されます。

i=1 i=1 18:26:36

ターミナル2

apache2を停止します。

$ sudo apachectl graceful-stop

ブラウザ1

ブラウザのクルクルは回ったままです。

ターミナル1

20秒待つと、2回目の日時表示が表示されました。リクエストスレッドの処理が最後まで処理されました。

i=1 i=1 18:26:36 i=1 18:26:56

実験4 apachectl graceful-stopしてからブラウザアクセスすると

ターミナル2

apache2を起動します。

$ sudo systemctl start apache2

ブラウザ1

http://localhost/longprocess.php?i=1 にアクセスします。

ターミナル1

すぐに表示されます。

i=1 i=1 18:26:36

ターミナル2

apache2を停止します。

$ sudo apachectl graceful-stop

ブラウザ1

ブラウザのクルクルは回ったままです。

ブラウザ2

http://localhost/longprocess.php?i=2 にアクセスします。

しかし、接続拒否でした。

ターミナル1

i=2 の表示はありません。

20秒待つと、i=1の2回目の日時表示が表示されました。リクエストスレッドの処理が最後まで処理されました。

i=1 i=1 18:26:36 i=1 18:26:56

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