nginx が Apache HTTP Server を抜いてWebサーバの1位になったそうですが、PHPな世界では Apache は未だ沢山使われています。
Apache2.4 で HTTP/1.1 から HTTP/2 に切り替える機会があったので、その手順と、高負荷テスト方法を残しておきます。
HTTP/2 は、より多くのスレッドやメモリが必要となるため、アクセス数の多いサイトでは十分注意の上で導入して下さい。
環境
バージョン情報
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
$ apache2 -v
Server version: Apache/2.4.41 (Ubuntu)
$ apachectl -V | grep MPM
Server MPM:
リソース情報
$ free -m
total used free shared buff/cache available
Mem: 3928 613 1790 67 1524 2986
Swap: 6143 443 5700
$ mysql
mysql> show variables like 'max_allowed_packet';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| max_allowed_packet | 67108864 |
+--------------------+----------+
mysql> show variables like 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+
mysql> show variables like 'innodb_log_file_size';
+----------------------+----------+
| Variable_name | Value |
+----------------------+----------+
| innodb_log_file_size | 50331648 |
+----------------------+----------+
mysql> show engine innodb status\G
Total large memory allocated 137035776
Dictionary memory allocated 753192
Buffer pool size 8192
Free buffers 6630
手順
MPM event + PHP-FPM の構成にします。
PHP-FPM の導入
apt install php7.4-fpm
a2enmod proxy_fcgi setenvif
a2enconf php7.4-fpm
a2dismod php7.4
apache2ctl configtest
prefork から event に変更
a2dismod mpm_prefork
a2enmod mpm_event
systemctl restart apache2
systemctl restart php7.4-fpm
HTTP/2 の有効化
a2enmod http2
systemctl restart apache2
バーチャルホストの設定変更
Protocols h2 http/1.1
チューニング
アクセスが集中してもサーバがダウンしないよう調整します。
mpm_event パラメータの調整
ServerLimit 700
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 700
MaxConnectionsPerChild 1000
php.ini パラメータの調整
FPM で php.ini の場所が変わるので注意。
memory_limit = 256M
post_max_size = 128M
upload_max_filesize = 128M
FPM パラメータの調整
pm = dynamic
pm.max_children = 100
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 8
pm.max_requests = 1000
実際には、Excelで設定ワークシートを作成しましたが、計算式については十分な裏どりが出来ていないので、公にしません。
Chromeでサイトに接続し、デベロッパーツールでプロトコルが h2 になっていることを確認します。
高負荷テスト
Apache JMeterを使う場合
JMeterは、昔からあるWebアプリケーションストレスツールです。ここからダウンロードできます。
Windowsの場合、setenvを次のようにすると日本語化できます。
set JMETER_LANGUAGE=-Duser.language="ja" -Duser.region="JP"
binフォルダにあるjmeter.batで起動します。
スレッドグループを作成し、HTTPリクエストの量と期間を設定していきましょう。
準備ができたので走らせてみましょう。
が、その前に、サーバ側でvmstat 1
コマンドを投入し、リソースをモニタリングしておきます。
ここでは、5秒間100スレッド(つまり秒間20アクセス)で指定してみます。
サーバ側でvmstat
の表示を確認します。プロセス数がみるみる増えていくはずです。
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
6 0 13312 2070800 91720 722412 16 0 16 2920 3102 4801 59 5 32 4 0
9 0 13312 2029308 91720 723908 0 0 0 2776 4019 5632 92 5 2 2 0
10 0 13312 2015832 91724 724564 0 0 0 3940 4815 7285 92 8 0 0 0
14 0 13312 1961132 91724 725220 0 0 0 3300 3821 6217 93 7 0 0 0
もしCPU利用率が100%近くで推移しているなら、CPUがボトルネック(メモリに対してCPUの能力が低い)と判断できます。
この場合、プロセスの起動に伴うオーバーヘッドがあるので、pm
をdynamic
からstatic
に変えると改善されるかもしれません。
Latency(リクエストを投げてからレスポンスが戻るまでの時間)は、JMeterのリスナーから確認します。
Apache Benchを使う場合
コマンドラインで使えるシンプルなツールです。
ab -n 100 -c 10 https://example.com
という感じで指定します。
-n
は総リクエスト数、-c
は同時リクエスト数です。
最後にレポートが表示されます。