WordPress 構築サイトの負荷軽減について

自サーバを何故か suEXEC と suPHP で構築してしまい、WordPress 構築サイトの過負荷で苦しんだのを何とかした際のメモ。

  • WP Super Cache を使う

    WordPress 側での対策として、「WP Super Cache」を mod_rewrite かつ、プリロードを有効として使用する。これだけでもだいぶん違う。

  • サイトへの過剰な接続を抑制する

    WP Super Cache は素晴らしく、これでおおよそ大丈夫なのだが、それでも過負荷に陥ることがあったので、Apache 側で mod_limitipconn か mod_bw を利用して、単一の IP アドレスからの過剰な接続を抑制する。

    • mod_limitipconn での例

      mod_limitipconn の場合は、Apache のバーチャルホストの設定部分に下記のような記述を行う。

      <Location />
      <IfModule mod_limitipconn.c>
      MaxConnPerIP 12
      NoIPLimit image/* text/css application/javascript
      </IfModule>
      </Location>

      当然ながら、取り得る値も例なので、サーバのスペックに合わせて要調整。
      上記の例では、同一 IP アドレスからの同時接続数は 12 を上限 (ただし、画像ファイルと CSS ファイル、JavaScript ファイルは除外) とする設定。

  • Apache からの子プロセスの数を制限

    上 2 点での設定でほぼ過負荷の問題は解決できるのだが、まだ一つ問題が残っている。それは 404 の処理。

    WordPress でパーマリンクのカスタマイズを行っている場合、記事や実ファイルが存在しない URL へのアクセスがあった場合でも、一旦 WordPress 上で 404 テンプレートの表示処理が走る。問題は、この 404 ページについては、WP Super Cache ではキャッシュされないので、これに F5 アタックなどをされてしまうと、いとも簡単にサーバのロードアベレージが上昇する。

    そこで、消極的な方法だが、Apache から起動する子プロセス数を制限してしまう。具体的には Apache のバーチャルホスト部分に下記のような設定を行う。

    RLimitNPROC 20 25

    これも取り得る値は要調整。上記は、ソフトリミット 20 プロセス、最大が 25 プロセス。(ただし私自身、実際のところ RLimitNPROC の説明を見ても、ソフトリミットと最大制限値の具体的な意味がよく分からないが、こう設定しておくことで最悪でも 26 プロセス以上は起動されないのであろう、と言う認識でこれを書いているので注意。)
    なお、この方法で CGI や PHP の起動プロセス数を制限するには、suEXEC 等、Apache の実行ユーザとは異なるユーザで CGI や PHP が起動されることが必要。

ほかにも mod-evasive を使ったりあれこれ試行錯誤を行ったが、最終的にはサーバ側でのリソース制限に落ち着いてしまう。(なんかスマートではない)

パーマリンクを WordPress のデフォルトの設定で使用すれば静的に 404 を表示できそうなので、そのまま使用するのが正しいと感じた。