RemitAid Tech Blog
💾

ある日突然起きた、LPの表示が遅い問題 —— Amazon LightsailにホストしたWordPressの内部プロセスを分析

に公開

こんにちは!
RemitAid CTOの@iTakacです。
創業間もない頃ですが、ある日突然サービスのLPをブラウザで表示させるのに数十秒かかってしまう事象が起きました。
https://remitaid.io/
今回はそのときに何が起きてどう解決したのかについて振り返りたいと思います。

LPはAmazon Lightsail + WordPress構成で管理

創業初期、ある程度サービスの方向性が固まった段階でLPをさくっと公開したい、ところが時間もお金もない、STUDIOは一定存在感がある中SEO的にどうなんだろ?などの疑問がありました。
従って自分たちの経験上、最も早く公開まで踏み切れる手段としてAmazon Lightsail + WordPressの構成でLPを公開していたのが当時の状況でした。

公開から数ヶ月経ったある日、LPを表示しようとするやけに重く、時には表示するまで数十秒ほどかかるときもありました。
当時は暫定的にLightsailのインスタンスを再起動することで対処していましたが、一定期間を経過するとまた再発します。

WordPressにおけるPHPサーバーのphp-fpmとは

WordPressはPHPサーバー上で稼働しているのですが、色々調査していくと何やらphp-fpmなる機構が想定外の挙動になっているのではないかという仮説に辿り着きました。(この時点でまだ解像度は粗いです)
php-fpmについては以下の記事がわかりやすかったので添付しておきますが、簡単に表すとアプリケーションとCPU/メモリなどのリソース間をうまく緩衝するプロセスコントロールです。
https://agaroot-itp.com/blog/1437/

当時の弊社環境の設定値は以下のようになっていました。
(環境構築以降、全くいじってないのでデフォルトかもしれません)

pm = dynamic               # プロセスが動的に生成される。staticとの切り替えが可能
pm.max_children = 15       # 同時接続可能数だがCPUのコア数に依存
pm.max_request = 5000      # プロセス再起動のトリガーとなる閾値
pm.max_spare_servers = 10  # 最大プロセス保持数
pm.min_spare_servers = 10  # 最小プロセス保持数

php-fpmをチューニング

仮説1:プロセスの待ち行列

この設定値から読み取れる原因の仮説は、同時接続されてしまうとCPUコア数に依存するプロセス数以上のプロセスが起動してしまい、プロセス演算中は他プロセスが待機状態となってしまったのではないか、というものでした。
1コアしかないpoorなインスタンスを選択していたので、より待ち行列化しやすかったのではと仮説立てました。

そこでGatlingを使って性能試験を実施。
結果としては同時接続ユーザー数3で5分間くらいであれば、起動プロセスが10個で捌けている状態でした。

つまり検証の結果として待ち行列が原因ではないことがわかり、仮説が外れました。

仮説2:メモリーリーク

次に疑ったのはメモリーリークによるハングです。
php-fpmのプロセスは1プロセスあたりおよそ80-100MBメモリー使用していました。
当時のスペックでいうと0.5GBのRAMだったので、5プロセスほどで枯渇します。
(ところどころで出現する貧乏スタートアップ感...スケールアップすりゃいいじゃんという声が聞こえてきそうです笑)

こちらも同時接続数を5以上に拡大し、数分間実行したところ再現はせず仮説は外れましたが、
5分を過ぎたあたりから滞留アクティブユーザーが目立つようになりました。

オレンジのグラフが滞留アクティブユーザー数の推移


50%tileが3秒以下

メモリーリークを引き起こしていた原因は2つあります。

  1. プロセスがpm.max_childrenの設定値どおり15プロセスまで起動していたこと
  2. プロセスが5,000を超えたタイミングで全プロセスが再起動したこと

特に2に関しては直感的にはプロセスが0に戻りそうですが、最後に起動していたプロセス数で起動し直していたことには驚きました。
メモリーリークという仮説は当たってましたが、リークを引き起こした真因が異なっていたのです。

従って以下のように設定値を変更しました。

pm = static           # プロセスを動的に起動しない
pm.max_children = 2   # 再起動時に立ち上がるプロセスのアップサイドを指定
pm.max_request = 50   # リークに達する前に頻繁に再起動できるように

Lightsailをburstable zoneからsustainable zoneへ戻す

上記のような設定を施し、あらためて性能試験を実施。
以下のグラフをご覧いただけるとわかるようにLightsailのインスタンスメトリクスも再起動時に明確にストンと負荷が下がるようになりました。

後日談

これだけ語っておきながら当社のLPは今はWordPressではありません笑
みなさまもよくご存知のSTUDIOでサイト構築しています。

当初懸念していたSEOに関しても以下の記事などを見ながら工夫すれば問題なさそうだと判断し、切り替えに踏み切っています。
https://www.itplus.co.jp/blog/studio-seo

なによりWordPressだとSSL証明書の準備と更新や今回の件のような負荷対応などに自社のエンジリニアリングリソースをがっつり取られてしまうことになり、toil(労苦)でした。
これらのお守りから解放されただけでも大きなメリットでした。

また単純にスケールアップしていたら得られなかったであろう知見を得られたことは知的好奇心という意味でも個人的には良かったです。

今回はphp-fpmをチューニングするという非常にニッチなテーマについて取り上げました。
ではまた次回の記事も乞うご期待ください!

告知

Podcast 「RemiTalk」では普段の会社の様子を赤裸々に語っています。
もし良ければ聴いてみてください!
https://podcasts.apple.com/jp/podcast/remitalk/id1826516525
Podcast 文字起こしはこちら
https://note.com/remitaid

またRemitAid では一緒に働く仲間を募集しています。
興味がある方はこちらからどうぞ!
https://youtrust.jp/recruitment_posts/ad655de82471df86af4f19469fe4c0de
https://youtrust.jp/recruitment_posts/7141d690aaa5ed348de45757da069e81

RemitAid Tech Blog
RemitAid Tech Blog

Discussion