一日に数回サーバ高負荷で応答がなくなってしまって困っていました。load average 90超え!!ありえん・・・
低性能なサーバなのに、大してApacheもMySQLものチューニングしていないからなあ・・・
ということで、最初はWordpressがアクセスしているMySQLが重たいのではと思い、メモリや接続数を少なくしてみたが効果なし。ということで、基本に戻って、まずは現状把握から。
sysstat パッケージでsarによる性能情報収集を開始し、topの結果を数秒おきにログに保存、さらに長い時間がかかるSQLもログに記録するようにしてみてわかったこと。それは、
- DoSアタックとは言わないが、同一IPからの大量アクセスが発生
- httpdプロセスが大量に生成
- 非力なサーバでスワップが発生しまくり
- 処理しきれずダウン
という典型的な非力サーバの事象でした。
で、httpd.confをよく見ると、ServerLimitやMaxClients がデフォルトで 256 と、非力なサーバでは処理しきれない値になっている・・。とりあえサーバの最大プロセス数を数個に削減。そんなにアクセスがあるサーバではないので問題ないと思う。
次に、同一IPからの連続アクセスは制限をかけました。
具体的には、mod_limitipconn というApacheモジュールを入れました。
これはその目的通り、同一IPからの接続を制限するためのモジュールです。epel のリポジトリに入っているので、リポジトリを設定している人であれば、インストールは
# yum install mod_limitipconn
とするだけです。リポジトリ設定していない人は、この辺りから適当にRPMをダウンロードしてインストールしましょう。
あとは、httpd.conf に
MaxConnPerIP 5
と追記して、apacheをリロードすれば、どういつIPからは5接続に制限できます。制限に達するとレスポンスコード503が返ります。
ちなみに、同じページに画像などが複数あると、この接続数に達して、画像が一部表示できないことがあります。なので、対象のディレクトリの設定で、
<Directory "/var/www/html"> ~ 省略 ~ NoIPLimit image/* </Directory>
と記述してあげれば、画像はこの制限から除外することができます。
参考 : Apache で同一IPからの接続数を制限する mod_limitipconn 設定方法