wp-cron.phpへのリクエスト数が半端ない
WordPressは特定の時間になったら特定の処理を行うというタイマー的な機能を実装するにあたって、WP-CRON
という仕組みを用意しています。これは通常WordPress上のいずれかのページへアクセスがあると、それと平行してwp-cron.php
へも同時にアクセスが発生し、その際に実行すべき処理があれば起動するというものです。つまりユーザーが1回アクセスすると必ず最低でも2回のアクセスが走ってしまう。
実際にアクセスログをざっくり集計すると、リクエストの27.5%程度がこのwp-cron.php
でした。
$ cat access_log | wc -l 82336 $ cat access_log | grep wp-cron.php | wc -l 22678
このブログはフロントにCDN(CloudFront)を置いているので、オリジンであるWordPressサーバには最小限のリクエストしか来ないのですが、拡張子に.php
が含まれる物はキャッシュ時間をゼロにして素通りさせている関係上、こいつだけはPV数分やってくるというわけです。そんなに上等なサーバ使ってないのでバズると死ぬw
というわけで、今回はwp-cron.php
へのアクセスを停止し、1分間に1回サーバ内部でWP-CRON
を実行する設定をします。
wp-cron.phpへのリクエストを停止する
WordPressをインストールしたディレクトリ配下にある config.php
を開き、適当な場所に以下のdefine
行を追加します。
$ cd /web/wordpress $ vi config.php define('DISABLE_WP_CRON', true);
ちなみに設定する値はfalse
にならなければ何でも大丈夫です。具体的には以下の関数でWP-CRONを実行するか判定しているのですが、このif文がtrue
になれば問題ありません。
### ./wp-includes/cron.php 内のコード
function wp_cron() {
// Prevent infinite loops caused by lack of wp-cron.php
if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false || ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ) )
return;
これでwp-cron.php
へのリクエストは止まったはずです。
cronからWP-CRONを起動する
このままだとバックアップ用のプラグインや、時間指定した記事が表示されなくなるっぽいのでWP-Cron
を別の方法で動かしてやります。
LinuxなどUNIX系OSに搭載されているスケジューラであるcronの設定をしてWP-Cron
を起動しようと思うのですが、ここではコマンドラインからWordPressを操作できるWP-CLI
を利用したいと思います。
WP-CLIのインストール
公式サイトの内容に沿ってインストールします。
## ダウンロード $ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar ## 実行権を付与 $ chmod +x wp-cli.phar ## /usr/local/bin/へ移動しコマンド化 $ sudo mv wp-cli.phar /usr/local/bin/wp
動作確認をするのですが、カレントディレクトリをWordPressをインストールしたディレクトリに移動しておくか、インストール先のパスを指定する必要があります。WP-CLIはwp
という名前のコマンドで叩くのが一般的です。--info
オプションで環境情報が表示されます。
$ cd /web/wordpress $ wp --info OS: Linux 4.9.77-31.58.amzn1.x86_64 #1 SMP Thu Jan 18 22:15:23 UTC 2018 x86_64 Shell: /bin/bash PHP binary: /usr/bin/php-7.1 PHP version: 7.1.23 php.ini used: /etc/php.ini WP-CLI root dir: phar://wp-cli.phar/vendor/wp-cli/wp-cli WP-CLI vendor dir: phar://wp-cli.phar/vendor WP_CLI phar path: /web/wordpress WP-CLI packages dir: WP-CLI global config: WP-CLI project config: WP-CLI version: 2.1.0
ちなみにパスを指定する場合は以下です。
$ wp --info --path=/web/wordpress
cronから実行するシェルスクリプトの準備
cronから直接wp
コマンドを叩いても良いのですが、今回はシェルスクリプトを1枚挟みます。
#!/bin/bash # # wp-cronをCLIから実行する # #--------------------------------------- # 定数 #--------------------------------------- # WORDPRESSをインストールしたディレクトリ WP_ROOT='/web/wordpress' #--------------------------------------- # 実行 #--------------------------------------- /usr/local/bin/wp cron event run --due-now --path=$WP_ROOT
実行権の付与を忘れずに。
$ chmod +x wpcron.sh
cronへ登録
先ほど作成したシェルスクリプトをcronに登録します。一般ユーザーで大丈夫です。以下のようにすると1分置きに実行してくれます。
## ファイルに記録しておく $ cat crontab.txt * * * * * /home/katsube/cron/wpcron.sh ## 登録 $ crontab < crontab.txt ## 登録状況を確認 $ crontab -l * * * * * /home/katsube/cron/wpcron.sh
cronが起動しているか確認
/var/log/cron
に記録されていますので、tailなどでのぞいて確認します。
$ sudo tail -f /var/log/cron Dec 30 12:55:15 ip-172-26-11-162 crontab[29605]: (katsube) REPLACE (katsube) Dec 30 12:55:18 ip-172-26-11-162 crontab[29606]: (katsube) LIST (katsube) Dec 30 12:56:01 ip-172-26-11-162 CROND[29620]: (katsube) CMD (/home/katsube/cron/wpcron.sh) Dec 30 12:57:01 ip-172-26-11-162 CROND[29627]: (katsube) CMD (/home/katsube/cron/wpcron.sh) Dec 30 12:58:01 ip-172-26-11-162 CROND[29667]: (katsube) CMD (/home/katsube/cron/wpcron.sh) Dec 30 12:59:01 ip-172-26-11-162 CROND[29708]: (katsube) CMD (/home/katsube/cron/wpcron.sh)
なお、このファイルは起動したかどうかしか記録されていませんので、正常に処理が行われたか調べるには出力結果をログなどに記録しておく必要があります。シェルスクリプトに手を入れて現在時間なども出力した方がわかりやすいですね。
$ cat crontab.txt * * * * * /home/katsube/cron/wpcron.sh >> /tmp/wpcron.log 2>&1
結果確認
よし ( ´∀`)bグッ
$ cat access_log | grep wp-cron.php | wc -l 0
技術評論社
売り上げランキング: 23,495