なぜだ!?(Rails x Apache)Apacheを再起動するまでは旧コードが走るのはなぜ?

motoya

概要

PM(見習い)のmotoyaです!

入社したばかりではありますが、
とんでもなく濃ゆい案件に関わった際にアウトプットしたいな♪
と思える知識に出くわしましたのでアウトプットさせて頂きます^^

前提

リリース前の手順として
デバッグ用に作成しリリース時に削除しなくてはいけないファイル が紛れていないか確認する手順を考えたとき

サーバー上のファイルを更新しても「Apache」を再起動するまでは旧コードが走り続ける特性
を利用してサーバー反映後に内部の確認するのが一番確実じゃない?

その特性ってApache上保証されるの???
という疑問から検討した内容になります!

対象読者

・私同様広く浅く生きている方
・バックエンドエンジニア

本題

結論

Apacheを再起動するまで旧コードが動作することを保証しているという理解は誤っており、
Railsのproduction環境設定が下記のようになっていれば保証される動作となります。

config.cache_classes = true

解説

config.cache_classes

Railsの公式では、config.cache_classesは下記のように明記されております。

3.1.6 config.cache_classes アプリケーションのクラスやモジュールをリクエストごとに再読み込みするか(=キャッシュしないかどうか)どうかを指定します。config.cache_classesのデフォルト値は、developmentモードではfalseなのでコードの更新がすぐ反映され、productionモードの場合はtrueなので高速に動作します。testモードでは、spring gemがインストールされている場合はデフォルトでfalse、そうでない場合はtrueになります。
https://railsguides.jp/configuring.html#config-cache-classes

上記より、重要な点は

  1. config.cache_classes = trueの場合は、アプリケーションのクラスやモジュールをサーバー起動時点でキャッシュする
  2. production環境のdefault設定は、config.cache_classes = trueである

の2点です。

なぜ、Apache(webサーバー)の再起動が焦点になったのか

以下のweb3層構造を念頭におきまして

基本的にサーバー構築段階でwebサーバーの起動・停止とアプリケーションサーバーの起動・停止は連動するように設定しています。 ※私は今まで空気のように感じてましたが、この設定にしてないとどっちかの起動忘れてエライことになるパターン多そうですね。。。

つまり、
Apacheの再起動を実施すると一緒にアプリケーションサーバーの再起動も実施される
ことになるため、Apacheの再起動が焦点になりました。

この話題のミスリード

railsでアプリケーション構築経験がある方は

[CentOS7]の場合
systemctl restart httpd

上記のようなコマンド実行しないと、サーバー側のソースコードを最新状態に更新しても本番環境に反映されない(;´∀`)

という経験した方は少なくないと思います。

つまり、webサーバーの再起動コマンドを実行しないと反映されないんだなと理解しちゃう方が少なくないのではと思いました。
※少なからず私はそうでした。。。

しかし、前項で述べたように
webサーバーを再起動しないと本番環境の更新が反映されない事象について
実際はアプリケーションサーバーの再起動がトリガーになっていて
それも、webフレームワーク側の設定次第で変更可能である

という理解が正しいのです。

所感

この話題を調査してると、
プロセス?、DSO?、共有オブジェクト?
なにそれ食べれるの。。。

という濃ゆいインフラ技術に足を突っ込んでしまったので
今後も継続して掘り進めてアウトプットしていきたいと思います!!!!!

ps.
CI/CDツールにチャレンジしたかった思い強し

カテゴリー: webアプリ

motoya