このブログ、Wordpress で構築しているんですけど最近になって php のエラーログに cron 再予約イベントエラーっていうのがちょくちょく出るようになって薄気味悪い。 Jetpack ちょっとなんとかしてよっていう話なんですけど、きっとなんとなくなんとなーくなんだろうなって思い、ちょっと考えてみました。
WordPress の中で cron みたいなのが機能しているのは有名な話で、アクセスがあるといっしょに定期処理をこなしましょうっていう体でのもので、アクセスの多いブログでは相当なサーバ負荷に通じると予想されるんですが(実際にはタイマーが仕込んであって wp-cron.php にアクセスするとなにがなんでも最後まで処理されるんじゃなくて、判定次第では途中で die してた)、ここはそんなにアクセスがあるわけでもなく、そういう意味合いで対処をしたいんじゃなくて、あくまでもエラーログが出るのが薄気味悪いっていう。
そんなにメチャ詳しくなくても wp-cron.php を読んでみれば(平たいコードなので読みづらいっていうのはあるものの) cron 的処理に行くまでにいくつもの条件分岐→ die っていうのがあって、それすらスルーできるのはいいんじゃないかっては思ったんですけど、そもそもこの wordpress cron は正式名があるのかっていう話がありますよね。 wp-cron って書いてみたり、「wp-cron.php を無効化!」って言いながら後で(システム側の) cron や launchctl で wp-cron.php を叩いたりして「それ無効化じゃないし?」みたいな感想を持ったり持たなかったりですけど、そもそも wp-config.php の最初の方で(っていうか最初で)
define (‘DISABLE_WP_CRON’, true);
ってしてアクセス時に wp-cron.php を読まないようにすると、アップデート更新や記事の予約投稿やらが行われなくなっちゃう。 アップデートは全部手動でやります!とか、予約投稿なんかしません!とか息巻くんであればいいんでしょうけど、自分以外の環境で、あまり言いたくはないけどアクセスの(以下略 えっとそういうのをしたいんであれば前述したとおり、システムレベルの cron( macOS であれば launchctl )で定期的に wp-cron.php を叩いてあげればいいわけで、例えば1秒に1アクセスあるような(1日で9万アクセスとかあるっていう意味で)サイトであれば、こっちで 15 分ごとに叩いてあげれば 15 * 60 – 1 分も節約できるっていうことでそりゃサーバに優しいっていう。 レンタルサーバでいくつもの多アクセスな wordpress ベースのサイトが稼働してるとなれば何をか言わんやであります。
さくらのレンタルサーバなんかでは cron は 1時間に1回にしてくださいね的なことが書かれてあり、ならば枠を4つ使って 15 分ごとにやっちゃえばよくね?みたいないいんだか悪いんだか悪いんだろうよ的な対処方法が考えつくと思うんだけど、他に廻したい定期処理が枠以上あったらどうするの?っていう予想も踏まえて当サイトではサーバ側で cron(実際は launchctl だけど)を使わないで定期処理をしていまして、予約投稿がうまいこと反映されたのでこの投稿をこれまた予約投稿(書いているのは 1/6 )する次第ではありますが、これだけは書きたいっていうことがあります。
トリガーからどう処理を行うかっていう話。 cron からシェルスクリプトでやるっていうなら問題はないんですけど、cron から php で wp-cron.php をインクルードしてやりたいという場合は注意が必要です。 上記の通り条件次第では die() を呼んで終了しますんで、いくつもインクルードできないっていう話です。 3サイト分それぞれ1つの php ファイルでインクルードで処理させたいとしたとき、最初のインクルードで die されたら残り2つはインクルードされないんですよね。 だもんでできるだけシェルスクリプトでやるか、どうしても php から使いたいのであれば、詳しくは書けないんですけど php から shell_exec でシェルスクリプトを呼べばいいです。 php を挟むと変なアクセスに対処できるからいいんですよね。 攻撃された場合の負荷を考えればちっちゃい話ですよ奥さん。