メモ > サーバ > 構築: チューニング > Apache チューニング
Apache チューニング
※preforkでのチューニング例
開発サーバや会員しか使わないサイトなら、設定する意味は少ない
短期間にApacheのプロセス数が大きく波打つようなサイトならチューニングが有効
(プロセスを作成するときの負荷を無くせるので)
基本的にはpreforkの設定はデフォルトのままで大丈夫
※Apacheに標準で付属している Apache Bench で、負荷テストができる
※Apacheの設定ファイル httpd.conf を編集してチューニングする
※Apache Bench でのテストを飛ばして、はじめからメモリ量をもとに考えても良さそう
【初心者向け】ApacheBench入門 | DevelopersIO
https://dev.classmethod.jp/tool/ab-tutorial/
Apache Benchを使った負荷テストのやり方
http://blog.verygoodtown.com/2012/05/apache-bench-ab/
同時接続数(MaxClients)をいくつに設定すべきか?
http://canalize.jp/archives/006925.php
Apache Benchでサクッと性能テスト
http://qiita.com/flexfirm/items/ac5a2f53cfa933a37192
404 Blog Not Found:tips - Webサーバーの負荷テストならまずab
http://blog.livedoor.jp/dankogai/archives/51212610.html
Apacheをインストールすれば自動的に使えるようになっているが、nginx環境などの場合は以下でツールのみインストールできる
# yum -y install httpd-tools
Nginx を使っているウェブサーバで ab(ApacheBench)コマンドを入れる | tamulab.jp
https://tamulab.jp/install-apache-bench-on-nginx-webserver/
XAMPPの場合、C:\xampp\apache\bin 内に ab.exe が存在している
Webアプリケーションへの同時アクセス対策メモ
http://refirio.org/view/367
■Apache Bench の実行例
$ ab -n 100 -c 10 http://refirio.net/ … http://refirio.net/ に対し、10人からのリクエストを100回実行
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking refirio.net (be patient).....done
Server Software: Apache
Server Hostname: refirio.net
Server Port: 80
Document Path: /
Document Length: 399 bytes
Concurrency Level: 10
Time taken for tests: 0.028 seconds
Complete requests: 100 … 成功したリクエスト(すべて成功)
Failed requests: 0 … 失敗したリクエスト(なし)
Write errors: 0
Total transferred: 65300 bytes
HTML transferred: 39900 bytes
Requests per second: 3518.15 [#/sec] (mean) … 1秒間に処理したリクエスト数(数字が大きいほど多く処理できた)
Time per request: 2.842 [ms] (mean) … 1リクエストあたりの処理時間
Time per request: 0.284 [ms] (mean, across all concurrent requests)
Transfer rate: 2243.51 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.5 0 2
Processing: 0 2 0.8 2 5
Waiting: 0 2 0.8 2 4
Total: 1 3 1.0 2 6
WARNING: The median and mean for the total time are not within a normal deviation
These results are probably not that reliable.
Percentage of the requests served within a certain time (ms)
50% 2
66% 3
75% 3
80% 3
90% 5
95% 5
98% 6
99% 6
100% 6 (longest request)
以下のようにするとkeepaliveの状態でテストできる
$ ab -k -n 2000 -c 200 http://refirio.net/
keepaliveの概要は以下のとおり
・接続を維持したまま複数のデータ転送を行える
・有効にすると通信が早くなる
・HTTP 1.1ではデフォルトで有効になっている
キープアライブ - Wikipedia
https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%BC%E3%83%97%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%96
HTTP-KeepAliveとは - コトバンク
https://kotobank.jp/word/HTTP-KeepAlive-10754
$ ab -n 3000 -c 35 http://refirio.net/ … http://refirio.net/ に対し、35人からのリクエストを3000回実行
Concurrency Level: 35
Time taken for tests: 0.749 seconds
Complete requests: 3000
Failed requests: 0
Write errors: 0
Total transferred: 1962265 bytes
HTML transferred: 1198995 bytes
Requests per second: 4006.01 [#/sec] (mean)
Time per request: 8.737 [ms] (mean)
Time per request: 0.250 [ms] (mean, across all concurrent requests)
Transfer rate: 2558.87 [Kbytes/sec] received
$ ab -n 3000 -c 35 http://refirio.net/blog/ … http://refirio.net/blog/ に対し、35人からのリクエストを3000回実行
Concurrency Level: 35
Time taken for tests: 68.335 seconds
Complete requests: 3000
Failed requests: 0
Write errors: 0
Total transferred: 20271000 bytes
HTML transferred: 19548000 bytes
Requests per second: 43.90 [#/sec] (mean)
Time per request: 797.242 [ms] (mean)
Time per request: 22.778 [ms] (mean, across all concurrent requests)
Transfer rate: 289.69 [Kbytes/sec] received
■負荷テスト
$ ab -n 1000 -c 100 http://refirio.net/blog/
Concurrency Level: 100
Time taken for tests: 26.575 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 6757000 bytes
HTML transferred: 6516000 bytes
Requests per second: 37.63 [#/sec] (mean)
Time per request: 2657.485 [ms] (mean)
Time per request: 26.575 [ms] (mean, across all concurrent requests)
Transfer rate: 248.30 [Kbytes/sec] received
$ ab -n 2000 -c 200 http://refirio.net/blog/ … Load Average が210くらいになったが、なんとかさばけている模様
Concurrency Level: 200
Time taken for tests: 1532.602 seconds
Complete requests: 2000
Failed requests: 0
Write errors: 0
Total transferred: 13514000 bytes
HTML transferred: 13032000 bytes
Requests per second: 1.30 [#/sec] (mean)
Time per request: 153260.231 [ms] (mean)
Time per request: 766.301 [ms] (mean, across all concurrent requests)
Transfer rate: 8.61 [Kbytes/sec] received
$ ab -n 3000 -c 300 http://refirio.net/blog/ … 「apr_poll: The timeout specified has expired」となった(このとき、Load Average が270くらいになった)
サーバに負荷がかかりすぎたようで、しばらくSSHもHTTPも繋がらなくなった
少なくともこのページでは300人からのアクセスはさばけない
Requests per second: 3518.15 [#/sec] (mean) …
1秒間に処理できるリクエスト数(Requests per second)がどんどん小さくなり、
1リクエストあたりの処理時間(Time per request)がどんどん多くなっている
これは、リクエストが多くなると処理待ちが多く発生するようになるため。
Apache Bench でのアクセスは、完全な同時アクセスではない
最初はアクセスが少なく、だんだん増えていき、一定数が続き、徐々に減っていく。という実際のアクセスを再現する
つまり、上の結果から「秒間200アクセスをさばくサーバ」と言えるわけでは無い
「200人の同時アクセスに耐えられるようにしてほしい」
の要件があった場合、
「秒間200アクセスをさばく」という意味なのか「200人が一定時間をかけて色々なページを見ている状況」
なのか確認しておく必要がある
普通のサーバなら、同時にさばけるのはせいぜい秒間数十くらい?
秒間100などという数字が出てきた時点で、ロードバランサでの複数台構成を考える?
ネットワークも考慮できる分、Apache Bench ツールよりLoadImpactの方が便利
だた、他のサーバからabツールを使えばネットワークを考慮に入れられる
Abを利用した負荷テスト時にTimeoutになる場合の対処法
http://qiita.com/y-mori/items/83547f4dd604e8e5c509
「TCP: time wait bucket table overflow」や「nf_conntrack: table full, dropping packet.」のエラーメッセージは無かった。
トップページへのリクエストなら大丈夫なので、負荷が高いページヘのリクエストだから問題があった?
今度は、普通のHTMLページに対してリクエストしてみる
$ ab -n 3000 -c 300 http://refirio.net/
Concurrency Level: 300
Time taken for tests: 1.470 seconds
Complete requests: 3000
Failed requests: 0
Write errors: 0
Total transferred: 1962265 bytes
HTML transferred: 1198995 bytes
Requests per second: 2040.96 [#/sec] (mean)
Time per request: 146.990 [ms] (mean)
Time per request: 0.490 [ms] (mean, across all concurrent requests)
Transfer rate: 1303.68 [Kbytes/sec] received
$ ab -n 5000 -c 500 http://refirio.net/
Concurrency Level: 500
Time taken for tests: 6.414 seconds
Complete requests: 5000
Failed requests: 0
Write errors: 0
Total transferred: 3273489 bytes
HTML transferred: 2000187 bytes
Requests per second: 779.53 [#/sec] (mean)
Time per request: 641.412 [ms] (mean)
Time per request: 1.283 [ms] (mean, across all concurrent requests)
Transfer rate: 498.40 [Kbytes/sec] received
$ ab -n 6000 -c 600 http://refirio.net/ … 完了できない
Benchmarking refirio.net (be patient)
Completed 600 requests
Completed 1200 requests
Completed 1800 requests
Completed 2400 requests
Completed 3000 requests
Completed 3600 requests
Completed 4200 requests
Completed 4800 requests
Completed 5400 requests
apr_socket_recv: Connection reset by peer (104)
Total of 5892 requests completed
# vi /var/log/messages … エラーメッセージを確認
CentOS6などでdmesgにpossible SYN flooding on port(SYN flooding警告)が出た場合の対策方法を考えてみるテスト
http://triplesky.blogspot.jp/2014/07/centos6dmesgpossible-syn-flooding-on.html
受け付けられないほどの大量アクセスが来たというログが残っている。
このサーバの接続可能数の飽和点は500程度。余裕を持たせて400程度
また先にテストしたように、PHPプログラムのページの場合は210程度が限界
ただしそのまま210に設定すると、他のサービスが稼働できないくらいの接続を受け入れてしまう可能性がある
また、swapも多発してサーバが非常に重くなる可能性がある
実際、abツールで計測している最中はサーバが非常に重くなった。
この状態ではサーバが落ちていなかったとしても「210をさばける」と言うわけにはいかない
■メモリ量からMaxClientsの目安を考えてみる
同時接続数(MaxClients)をいくつに設定すべきか?
http://canalize.jp/archives/006925.php
MaxClients=使用可能なメモリ量/Apacheの1プロセスが使用するメモリ量
という考え方で計算できる
refirio.netサーバではメモリは1GBで、実際に使っているのは500MBくらい。
psで見ると、httpdの1プロセスが2%くらいを使っているので、1プロセスあたり10MBくらい使っている
よって、MaxClientsは90〜100くらいが良さそう
↑の数値はRではなくSのプロセスだし、データベースなども考慮する必要がある。
常時立ち上げるなら80くらいでもいいかも?
(ただし例えばMySQLを使うなら、MySQLのmax_connectionsとの兼ね合いも考慮する)
Sのプロセスでメモリの消費量を計算すると、実際はもっと消費する可能性があるので注意
ある程度サーバに負荷をかけてRのプロセスを表示させ、それをもとに計算した方がいい
#なお、某大学の入試サイトサーバではメモリは16GBで、実際に使っているのは1.4GBくらい。
#psで見ると、httpdの1プロセスが0.1%に満たないくらいを使っているので、1プロセスあたり1.4MBくらい使っている
#refirio.netとは大きく差があるが、1プロセスあたりの消費メモリは、実行されているプログラムによっても変わる
#また、長い間プロセスが使われていないとメモリ量はどんどん小さくなるらしい
#このサーバはスペックが高いので、他のプロセスが使われないので、最小状態になっている?
#Apacheの使用メモリが搭載メモリ数を超えてしまうと、スワップが発生してサーバが重くなる
#逆に少なすぎると503エラーになる
/etc/httpd/conf/httpd.conf を編集
kernel: possible SYN flooding on port 80. Sending cookies.
<IfModule prefork.c>
StartServers 8 … 起動時に生成される子サーバプロセスの数。常に動かしておきたい数に設定しておく
MinSpareServers 5 … アイドル状態にいる子サーバプロセスの最小(希望)個数
MaxSpareServers 20 … アイドル状態にいる子サーバプロセスの最大(希望)個数
ServerLimit 256 … MaxClientsに指定可能な値の上限
MaxClients 256 … 起動される子サーバプロセスの最大数。つまり応答できる同時リクエスト数
MaxRequestsPerChild 4000 … 個々の子サーバプロセスが扱うことのできるリクエストの総数。0に設定すると無制限
</IfModule>
一旦以下のように変更する
<IfModule prefork.c>
StartServers 80
MinSpareServers 80
MaxSpareServers 80
ServerLimit 80
MaxClients 80
MaxRequestsPerChild 0
</IfModule>
これで様子を見つつ、エラーログに以下のメッセージが記録されたら、400までの値で少しづつ上げて調整する
[error] server reached MaxClients setting, consider raising the MaxClients setting
400まで上げてもエラーログがでるようなら、もうその1台のサーバでは対応できない(Apache的に)ので、
ロードバランサで複数台構成を検討する必要がある
また、これはあくまでもサーバスペックのみでの話。実際には転送量制限や帯域制限もあるので注意。
Apacheのチューニングメモ
http://qiita.com/nownabe/items/1111cc32da9fe63289f0
中規模サイトのApacheチューニング
http://qiita.com/kou/items/acb3dcf1dcb428d7a3ec
他にも以下を設定しておくと良さそう
Timeout ... 60秒でも長い?10秒くらいでいいかも(ただしAWSの場合は120に設定する)
KeepAlive ... OFFでよさそう(AWSの場合は有効に設定する)
Amazon ELBをうまくつかうには、KeepAliveを有効にしよう。Timeoutは60秒よりだいぶ長くしよう。その背景。
https://debiancdn.wordpress.com/2012/06/14/amazon-elb%E3%82%92%E3%81%86%E3%81%BE%E3%81%8F%E3%81%A4%E...
※今はサーバスペックが向上しているので、回線(帯域)の方がネックになることがある
帯域をもとに同時にさばける数を計算し、それをもとに判断するという手段もある
※サーバ契約前・構築前ならどのように判断する?
■負荷をかけずに速度計測
以下のように「-c 1」にすれば単一の接続になる
また、リクエストの回数も「-n 10」と少なめにする
$ ab -n 10 -c 1 -k http://refirio.net/blog/
Netlifyが日本からだと遅い - id:anatooのブログ
https://blog.anatoo.jp/2020-08-03