WordPressの負荷軽減を本気でやってみたら負荷が1/3になった

PR

最近サーバーのコンパネを見てなかったのですが、いつしか負荷が増えて503が頻発する自体になっていました。借りているレンタルサーバーはさくらインターネットのレンタルサーバーで、もう何年も利用しているものです。

何個もWordpressのサイトを動かしていて結構こき使ってきてましたので、ここで改めてWordpressの負荷軽減を本気でやってみました。

 

WordPressの負荷軽減策

まず、なぜこんなに負荷が増えたのかってところから考えて

  • 攻撃が増えてきた
  • アクセスが増えてきた
  • プラグインが悪さしている(重たい)

この両面から対策していくことにしました、まずは攻撃による負荷増大です

WordPressは世界一利用されているCMSです、そのぶん構造が周知されており攻撃の対象とされやすいです、攻撃自体はこれまで防げてきていますが攻撃自体がなくなっているわけではない

またこの攻撃ってのがGoogleアナリティクスとかのアクセス解析とかには出ないもので、サーバーでは単なるPVとしてしか認識されてないので判断しにくいのですが、攻撃されるポイントを塞いでしまおうということでそれからサーバーの負荷の減り具合をみて、実感すれば良いということで対策を練ります

 

また503が発生する理由としては短時間に集中してアクセス(プログラム実行)がおきてしまっているときです。

 

WordPressへの主な攻撃手段

WordPressへの主な攻撃手段は2つ

  • xmlrpc.phpを狙った攻撃
  • wp-login.phpを狙った攻撃

まずxmlrpc.phpですが、これは何に使われているかというと ブログエディタやモバイルからのブログ投稿、ピンバック・トラックバックの処理などに使われています。

自分のサイトでは、ピンバックもトラックバックも受け付けていません、さらにモバイルからの投稿もしてませんしブログエディタも昔は使っている時期がありましたが、現在はWordpressのビジュアルエディタの方が優秀になったので使う機会がなくなりました。

ということで、xmlrpc.phpの昨日は一切使っていませんので最も攻撃を受けやすいxmlrpc.phpへのアクセス制限を行うことにしました。

 

xmlrpc.phpへの攻撃対策

攻撃対策ですが調べてみると何通りか対策方法があります

  • xmlrpc.php 自体を削除する
  • xmlrpc.php へのアクセスを .htaccess で制限する
  • xmlrpc.php へのアクセスを転送する
  • WordPressのプラグインで対策する

おもにこれらが対策の方法となると思いますが、Wordpressのプラグインを使う方法はまず無しです。プラグイン自体がサーバーへの負荷増大につながるので今回の目的は負荷軽減がメインですので。

xmlrpc.php 自体を削除する方法も基本的にはなしです、Wordpressのインストールフォルダの1階層目にあるファイルなのでFTPからサクッと消すだけで出来る最も簡単で.htaccessとかわからない人でも有効な対策ではありますが、Wordpressをアップデートする度に復活してしまいます。Wordpressのアップデートは上書き方式なので、消したファイルは新たに出来ます。

そのため、Wordpressの更新をしてxmlrpc.phpの消し忘れがある溜め面倒です、またWordpressのサイトが多いとそのぶん対処が増えてきます。

 

そして、使い勝手が良いのが2つ残ります

アクセス制限をする方法とアクセスを転送する方法です

この2つで負荷が少ないのはアクセスを転送する方法です、何故かと言うとアクセスを制限する場合は

  • サーバーへのアクセス
  • サーバーからアクセス禁止のレスポンス(← これが負荷に)
  • 2回目のサーバーへのアクセス
  • サーバーからアクセス禁止のレスポンス(← これが負荷に)
  • 以降同じ

となります、xmlrpc.phpへのアクセスへのレスポンス自体はサーバーが返しているので負荷が発生しますxmlrpc.php自体を消してしまっても、ファイルがないというレスポンスをサーバーが返しているので同じく負荷があります。もちろん、通常のxmlrpc.phpのアクセスよりも処理が短いので負荷は減りますが

 

アクセスを転送する場合は

  • サーバーへのアクセス
  • 1回目はサーバーから転送先を記したレスポンス(← これは負荷に)
  • 2回目のサーバーへのアクセス
  • 実際には自分のサーバーにはアクセスしておらずアクセス元が転送先をキャッシュしており、ダイレクトに転送先へアクセスする(負荷なし)
  • 以降キャッシュされている限りこちらのサーバーには負荷は発生しない

こういった原理です、1回目はどうじてもレスポンスが出ますが2回目以降はアクセス元が転送(リダイレクト)をキャッシュしている場合は直接キャッシュ先へアクセスします。

アクセス元がキャッシュしない仕様ならばレスポンスが発生してシマノで負荷が発生してしまいますが、2回目以降のアクセスでの負荷ゼロが期待できます。

 

実際に .htaccess への記述

#XMLRPC STOP START
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^xmlrpc\.php$ "http\:\/\/0\.0\.0\.0\/" [R=301,L]
</IfModule>
#XMLRPC STOP END

これWordpressがインストールしてあるディレクトリにある .htaccess に書き加えて完了です。最後尾に書き加えた場合は かならず複数改行しておきましょうサーバーの設定によっては、改行がないとうまく .htaccess が動かない自体が発生します

転送先は 0.0.0.0 となってます、これが別に Google でも良いです、ただ自サイトにすると負荷軽減になりませんのでご注意を、ちなみに 0.0.0.0 というのはサーバーのアクセス元の内部にアクセスだったと思います。

 

WordPress wp-login.php へのアクセス対策

こちらはセキュリティ対策ですね、私の場合はサーバー全体で wp-login.php へのアクセスを指定IPでしかアクセス出来ないようにしています、サーバーが提供している国外IPからのアクセス禁止が有効になっているので、攻撃自体はそれほど無いようです

これはサーバーのエラーログをみると、wp-login.php へのアクセスが失敗しているのを簡単に見つけれます。

今回はこの設定はこれまで通りで過ごそうと思います、IP指定でそれ以外はリダイレクト処理にするとことで負荷軽減も可能でしょうが、自身のPCのIPが変わった時にリダイレクトされてしまうとブラウザがキャッシュしてしまってキャッシュの削除とか面倒なので、そのままで行きます。

 

ちなみに ルートディレクトリにて以下のように設定して 指定IP以外からは wp-login.php へのアクセスを制限しています、固定IPの回線ではなくルーターの再起動等で自身のIPが変わってしまった場合はこのファイルを適時書き換えています。

# 特定のIPのみ ログイン
<Files wp-login.php>
Order deny,allow
Deny from all
Allow from xxx.xxx.xxx.xxx #許可するIPアドレス
</Files>

xxx.xxx.xxx.xxxのところには自身のIPを入れるところになります。

 

WordPressへのアクセス増に対する負荷軽減策

続いては攻撃ではない普通のアクセスによるWordpressへの負荷軽減策となります

いろいろ調べるとWordpressにはwp-cron.phpっていう便利ではありながら厄介なものがあります、これは擬似的にcronを実現するためのファイルなのですが、これが一番負荷が高でした

何をしているかと言うと、cronってのは定時にプログラムを実行させるためのものなのですがWordpress自身はそういうことが出来ません、なのでWordpressへのアクセスがあったときにWordpressが溜め込んだタスクをそのアクセスの時間を元に時間が過ぎているのかどうか判断してプログラムを実行させます。

この時間の判断が実はアクセス毎なので相当負荷がかかっていると言えます、実際にタスクがなくても色々プログラムが走るので無駄な処理が多くなります。

その他に対策を行うべきなのが

  • プラグインの見直し
  • キャッシュプラグインの設定の見直し

単純に要らないプラグインを消しましょうということです、またキャッシュプラグインもサイトのスタイルに適したものにしましょうということです。

 

wp-cron.phpの実行を停止する

まずはwp-cron.phpですが、コレ自体はWordpressにとって必要なものですコレがないとうまく動作しないプラグインも存在しますし、Wordpressの基本機能の予約投稿もwp-cron.phpを利用しています

これがないと予約投稿がうまく動きません、中にはWordpressでサイトをつくってアクセスが少ない時期に予約投稿がちゃんと投稿されてなかった、なんて体験した人も要るんではないでしょうか?この原因は wp-cron.php がサイトのアクセスをトリガーとして動いているため、アクセスが全くなければ wp-cron.php が実行されないためです、そのため予約投稿が実行されなかったのです。

自身がサイトを見ると予約投稿が公開されたなんてこともあるでしょう、例えばローカルサーバーで立てたWordpressなんてのはアクセスが出来るのは自分自身なので予約投稿は機能しなかったりしますね。

 

なのでこのwp-cron.php 自体は使い方によって必要な機能だったりしますので、その点をケアしてやる必要がありますが、私のケースでは予約投稿を基本的に使ってなかったりするので今回は単純にwp-cron.phpの機能を停止してやって、必要になってくればサーバーのcronにて定時にwp-cron.phpの実行をさせて対処しようかと思います。

 

wp-cron.phpの停止方法

/* CRON STOP */
define('DISABLE_WP_CRON', 'true');

wp-config.phpというファイルがWordpressのインストールディレクトリにあるかと思います、それの最後らへんにでも書き加えてく保存してください、これでWordpressへアクセスがあってもwp-cron.phpは実行されなくなります。

wp-cron.php自体の機能は死んでいないので、cronでこのファイルにアクセスしてやると動きはします。

たとえば1時間100PVあるサイトなら、これを1時間に1回サーバーのcronで実行する形にするだけでwp-cron自体は機能させて1/100の負荷へと軽減出来たことになります。

ただし1時間に1回なので予約投稿とかはそのアクセスがあった時間に実行されることになりますので、この間隔を狭めてやりたい場合は実行時間の間隔を短くすればよかと思います。

 

改めて503が発生する理由はサーバーの処理能力が一時的に超えてしまったっという意味ですから、集中的にアクセスが有る時に wp-cron.phpが大量に実行させないというところさえクリアできていれば良いので、cronによるwp-cron.phpの実行の間隔は意外と短くても問題は無いのだろうと思います。

特にwp-cron.phpの標準の仕様がネックになるのは、アクセスが集中すればするほど実行されてしまう点ですから。

 

WordPressのプラグインの見直し

こちらは基本的に使わないプラグインを消しました、要るか要らないかはそれぞれのWordpressの使い方に大きく依存するので、熟考してプラグインを選別するしか無いです。

 

WordPressのキャッシュプラグインの設定の見直し

キャッシュプラグイン自体も負荷の原因にもなりえますが、設定を煮詰めることで最大のパワーを発揮させれます。

キャッシュプラグインっていうのは有効にするだけでも十分に機能してますが、初期設定は無難な設定となっていますどのサイトでも問題なく動くだろうという想定の設定です。

 

私が使っているWordpressのキャッシュプラグインはもともとは WP Super Caceh でしたが、PHP.7.1からなんだかエラーで大変なことになったので今は W3 Total Cache を利用しています。

このプラグインを有効にしてそのままつかっていたのですが、細かくチェックしてみるとキャッシュの設定時間がとても短かったです、この設定だと結局のところはアクセスする度に処理が実行されるのでキャッシュ時間を変更しました

もともとは180秒のライフタイムのキャッシュで1時間で古いキャッシュの削除という設定でした、これはあまりにも短すぎる気がします、これをとりあえずは1時間ベースに置き換えましたライフタイムは3,600秒(1時間)、古いキャッシュの削除は86,400秒(24時間)

もともとの2分設定はかなり更新が頻繁なサイトで一般的ではないでしょう、一時的なアクセス集中時には対応できるのかもしれませんが慢性的なアクセス集中には対応できないでしょう、ましてやページ数が多いサイトでは意味をなさないどころかキャッシュの生成にリソースを持ってかれて負荷が倍増するでしょう。

またキャッシュされた部分ってのは新たにページが投稿されたりすると、更新があった箇所は破棄されて新たにキャッシュが作られる用になったりするので新規ページってのはこのキャッシュ時間の長短の影響は無いでしょう。

影響があるとしたら、既に投稿してある記事の変更やデザインの変更を行ったりしたケースだと思います、そういう場合はキャッシュ全てを破棄するボタンもありますのでその時にキャッシュをクリアしてやれば良いでしょう。

 

私のケースではオブジェクトキャッシュとDBキャッシュの時間をそれぞれ ライフタイムは1時間、キャッシュの破棄は24時間にしましたがこれはまだ様子見です。毎時更新するようなサイトでも無いですし、コメントも大量に来るわけでもありませんのでもっと長くしても良いかと思います。

キャッシュをうまく使えばスタティックなサイトと同等でありながらCMSの良さを取り入れることが可能ですので、キャッシュ設定は重要ですね。(有効だけしてちゃんと設定を煮詰めてなかったのを反省)

 

WordPress負荷対策の結果どうなったか

ここまで色々とWordpressの負荷対策を施してきたわけですが結果的にどうなったか?ってのが重要ですね

結果から言うと、直近のピーク時に比べてCPUの使用時間は1/3以下まで抑えることが出来ました、一部使い勝手は下がった面がありますが大した問題でも無いです。

そして503発生はゼロになりました。

青色がCPUの使用時間です、ピーク時は8時間超えでした。負荷対策は実は段階的に行って効果を見ながらだったので急激にガクンと落ちるのではなくジリジリ下がっていく形になっています。これはちゃんと効果がそれぞれあったのかを見るためです。あと、日単位なので丸一日効果を見るには数日空けてから次の対策って感じでやって行きました。

サーバーへのPV自体も相当減りました、転送量も減りました、これはwp-cron.phpへのアクセス減、xmlrpc.phpへのアクセス減が相当効いている証拠だと思います、Googleアナリティクスではアクセスは普段と然程変化がない感じでもありましたのでユーザーが減ったってわけでも無いです。

そしてもう一方のグラフが503の発生回数です、9月27~9月30日のところ一旦ゼロとなっているのは、さくらインターネットのレンタルサーバーにあるブースト機能を試してみたからです、このブースト機能ってのはサーバーの処理能力を2日間大幅に解放してくれるもので、サーバーの処理能力が上がったことで503が発生しなくなったってことです。

これをきっかけにサーバーの移転も考えましたが、負荷軽減をまずやってみるってことで結果的に成功しました。まだまだこのサーバーでやって行けそうですね。

 

小話ですが

実は、この503大量発生が発覚したタイミングってのがさくらインターネットサーバー更新確定後だったわけですよ、サーバー乗り換えようにも1年更新が確定してしまっていてあとは支払い請求待だったわけで、請求される前に解約して他のサーバーへってのも出来なくはないんですが

サーバー移転には時間の余裕を持ってやりたく月更新に変更したかったのですが期限が過ぎてたってわけで、もう負荷軽減やってみるしか無いってところだったわけです。サーバーにお金を潤沢に掛けれる人は、難しいこと考えなくてもサーバーを増強すれば解決できます。ただ規模が大きくなればなるほど負荷軽減策による費用対効果は大きくもなりますけどね。

あとはさくらインターネットのレンタルサーバーでメンテナンス期間でもあったのでその影響もある程度煽りを受けたのかなとも考えていますが

大幅に負荷軽減ができ、また良い経験となりました。サイトのレスポンスもアップしたようで、ユーザーにもより快適にサイトが見てもらえるようになったんではないかと思います。

PR

COMMENT

コメントを残す

PR

9ineBBの管理人が運営するサイト

WDG WEB DESIGN GALLERY ウェブデザインギャラリー