PHPを含めたミドルウェアバージョンアップを行ったらパフォーマンス劣化が発生し、php_infoを確認したら原因がわかった件について

# はじめに
所属しているチームで運用保守しているサーバーのミドルウェアアップデートを行っております。
サーバーが運用に耐えられるのか確認するため、JMeterを利用した負荷試験を実施しました。

負荷試験の期待値としては、現在と変わらない、または、ミドルウェアのアップデートによる処理効率の上昇で良くなると想定しておりました。
しかし、移行後のサーバーでの結果が移行前のサーバーより平均応答時間等が全体的に悪い結果となりました。

移行後のサーバーのパフォーマンスを改善するために、何を調査したか、結果的にどこに問題があったのか、備忘録として残したいと思います。

### アップデートを行ったミドルウェアについて
+ PHP
+ Apache

### 負荷試験対象のサーバースペックについて
クロック周波数の違いはありますが、移行前・移行後で同スペックで構築しました。

|サーバー|CPU（クロック周波数）|CPU（コア数）|メモリ|
|-|-|-|-|
|移行前開発サーバー|2.00GHz|2|8GB|
|移行後開発サーバー|2.20GHz|2|8GB|

### JMeterのシナリオについて
良く使われているユーザー操作を想定して以下の画面遷移を行うようにシナリオを設定しました。
```ログイン画面 → TOP画面 → 在庫一覧画面 → 在庫一覧画面での非同期通信処理```

スレッド数、Ramp-Up期間（秒）、ループ回数を決めるために、
総リクエスト数を取得して各ピーク時のアクセス数を調査しました。

|1時間あたりのリクエスト数|1分あたりのリクエスト数|1秒あたりのリクエスト数|
|-|-|-|
|32,266|1,092|39|

上記の2つの結果を組み合わせて、負荷試験シナリオを作成しております。

# 負荷試験実施とパフォーマンス低下の原因調査について
原因特定までの負荷試験結果と問題切り分けを行った調査記録となります。

## 負荷試験１回目
### 実行結果

|サーバー|スレッド数|Ramp-Up期間（秒）|ループ回数|Label|総リクエスト数|平均応答時間（ms）|
|-|-|-|-|-|-|-|-|
|移行前開発サーバー|234|60|10|合計|15,210|5,971|
|移行後開発サーバー|234|60|10|合計|15,210|7,382|

JMeterを利用するのが初めてだったためパラメータへの理解度が低く、想定より高負荷を掛けてしまいました。
この段階でも移行後開発サーバーの方が遅い結果になっておりましたが、アクセス数からの適切な負荷を与える事に決定しました。

## 負荷試験２回目
1回目は負荷が高すぎたため、同時アクセスを適切に設定しつつ負荷を掛け続けるようなシナリオ作成を行いました。

### 実行結果

|サーバー|スレッド数|Ramp-Up期間（秒）|ループ回数|Label|総リクエスト数|平均応答時間（ms）|
|-|-|-|-|-|-|-|-|
|移行前開発サーバー|110|600|100|合計|66550|<strong>1878</strong>|
|移行後開発サーバー|110|600|100|合計|66550|<strong>3190</strong>|

同時アクセス数を多く設定したシナリオで約1.3秒も遅くなっていました
この結果を受けて、移行後開発サーバーに問題があると推測して調査を行う事に決定しました。

## 問題切り分けのために行った事
どこの部分が問題があるか、現段階では不明なため切り分けを行いました。

### 原因推測
* ロードバランサー（LB）を利用しているので、ここでボトルネックや問題が発生していないか確認する。
* 移行後のソースはセキュリティ対応等の追加対応を行っているため、これが問題になっていないか確認する。
* サーバー設定に問題が無いか確認するために、移行前の開発サーバーで移行後のソースを反映して負荷試験を実施する。

#### ロードバランサー確認結果
開発サーバーは2台用意してあるので、1台のみに負荷が向くようにパーシステンスをJMeterで設定して負荷試験を実施しました。
結果、2回目とほぼ同等の結果となりましたので、LBには問題が無い事が判明しました。

#### ソース修正前後での負荷試験結果
負荷試験を実施した所、修正前後でほとんど処理時間に差は見られませんでした。
そのため、セキュリティ対応は問題が無い事が判明しました。

#### 移行前開発サーバーでの負荷試験結果
負荷試験を実施した所、移行前開発サーバーで動作させた方が良い結果となりました。
サーバー設定に問題がある可能性が高いと思い、詳細調査する方針に決定しました。

## サーバー・ミドルウェア設定ファイル確認
ミドルウェア設定に問題がある可能性が高いと推測して、
サービスで利用しているApache、PHPの設定調査を行いました。

#### Apache設定ファイル確認
httpd.conf ファイルを移行前開発サーバー、移行後開発サーバーから取得して差分があるか確認。
LoadModule等のいくつかの設定がコメントアウトされていて読み込めておりませんでした。

#### PHP設定ファイル確認
php.ini ファイルを移行前開発サーバー、移行後開発サーバーから取得して差分があるか確認。
ミドルウェアアップデートとして、PHP7.0からPHP7.3にアップデートを行っているため、ほぼコメントでの差分のみが出力されておりました。

#### 設定ファイル差分を修正して再度負荷試験実施
設定ファイルを修正して再度負荷試験を実施しました。
結果は、修正前と差が出なかったので特に影響が無いという事が判明しました。

# パフォーマンス低下の原因判明、改善後の負荷試験結果
サーバーの設定に問題がありそうな所までは突き止めていましたが、PHP・Apacheの設定ファイル以外にパフォーマンスに影響がありそうなミドルウェアが思い浮かばず、調査が難航してしまっておりましたが、ふと、php_info結果を比較していないと気付き確認を行ってみた所、以下の箇所に差分が見つかりました。

+ 移行前開発サーバーでのPHP_INFO結果
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259227/fb75f96c-bd3c-22c8-55c6-2735c5efad42.png)

+ 移行後開発サーバーでのPHP_INFO結果
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259227/effb522c-d9e3-da2d-ac59-d404387648f6.png)

結果としては、必要なPHP拡張機能が読み込まれていなかったので、移行後開発サーバーが遅くなっておりました。

移行後開発サーバーに必要な拡張機能を精査して、PHP再コンパイルを行い。
再度負荷試験を実施しました。

|サーバー|スレッド数|Ramp-Up期間（秒）|ループ回数|Label|総リクエスト数|平均応答時間（ms）|
|-|-|-|-|-|-|-|-|
|移行前開発サーバー|55|600|100|合計|33275|1024|
|移行後開発サーバー|55|600|100|合計|33275|972|
移行後開発サーバーの方が平均応答時間が早くなる結果となりました。
負荷試験の期待値まで持っていけたので負荷試験は完了となります。

# まとめ
+ **PHPで何かしらの問題が発生したら、php_infoを確認しよう！**
+ **どこで問題が発生しているのか仮設を立てて、原因の切り分けを行おう！**

パフォーマンス問題は、ハードウェア・ネットワーク・ミドルウェア・各種設定値など、様々な要因があると思います。
そのため、仮設を立てて一つ一つ問題を整理していく必要があると思います。
同じパターンとなる事は無いと思いますが、何かご参考になりましたら幸いです。

# 参考リンク
貴重な情報を頂きありがとうございました！

+ [JMeter のインストールから負荷テストまで](https://qiita.com/shotets/items/d553d7be0d407a9a9a53)
+ [JMeterのパラメータについて](http://webmemo.uzura.work/article/2507)
+ [PHPスキャンディレクトリについて](https://www.php.net/manual/ja/configuration.file.php#configuration.file.scan)