エロサイトの作り方

2013年11月から勉強しながらエロサイトを作っています。

WordPressで予約投稿が失敗する

最近、予約投稿ができずに、管理画面上で「予約投稿の失敗」と出ることが増えてきたので、ちょっと調べてみました。

何が起きているのか?

とりあえず、PHP-FPMのエラーログに何か手がかりが無いか見てみる。

[21-Aug-2014 00:43:22] NOTICE: child 30278 stopped for tracing
[21-Aug-2014 00:43:22] NOTICE: about to trace 30278
[21-Aug-2014 00:43:22] NOTICE: finished trace of 30278
(01:10が予約投稿時間)
[21-Aug-2014 01:10:14] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
[21-Aug-2014 01:10:16] WARNING: [pool www] child 26864, script '/var/www/wp-cron.php' (request: "POST /wp-cron.php") executing too slow (6.366237 sec), logging
[21-Aug-2014 01:10:16] NOTICE: child 26864 stopped for tracing
[21-Aug-2014 01:10:16] NOTICE: about to trace 26864
[21-Aug-2014 01:10:16] NOTICE: finished trace of 26864
[21-Aug-2014 01:10:54] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
[21-Aug-2014 01:11:09] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
[21-Aug-2014 01:28:40] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it

関連しているかもしれないWARNINGが2種類出てますね。

同時接続数を超えている

[21-Aug-2014 01:10:14] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
[21-Aug-2014 01:10:54] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
[21-Aug-2014 01:11:09] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it

直接の原因はこれっぽい。同時接続数の上限で処理ができなかった。

処理が遅い

[21-Aug-2014 01:10:16] WARNING: [pool www] child 26864, script '/var/www/wp-cron.php' (request: "POST /wp-cron.php") executing too slow (6.366237 sec), logging

同時接続の上限になったのは処理が遅いからのようです。wp-cronが6.3秒もかかっている。

そもそもWordPressのレスポンスはNginxでキャッシュしているので普通のリクエストは来ないため、/wp-cron.phpが呼ばれただけで重たくなっているように思える。

というか、cronっぽい仕組みをユーザーからのリクエストで回しているのがそもそもおかしいんだけど、そういう実装になっているからなぁ……

遅い処理の内訳

PHP-FPMのスロークエリログに何か出ているかも。

[21-Aug-2014 01:10:16]  [pool www] pid 26864
script_filename = /var/www/wp-cron.php
[0x00007f71b0d2bcf0] mysql_query() /var/www/wp-includes/wp-db.php:1619
[0x00007f71b0d2b180] _do_query() /var/www/wp-includes/wp-db.php:1523
[0x00007f71b0d2ae80] query() /var/www/wp-includes/wp-db.php:1824
[0x00007f71b0d29fd0] get_var() /var/www/wp-includes/functions.php:504
[0x00007f71b0d294a8] do_enclose() /var/www/wp-content/plugins/wordpress-ping-optimizer/cbnet-ping-optimizer.php:327
[0x00007fffbf76a470] cbnetpoPingServices() unknown:0
[0x00007f71b0d28d28] call_user_func_array() /var/www/wp-includes/plugin.php:546
[0x00007f71b0d28340] do_action_ref_array() /var/www/wp-cron.php:100

見方がよくわからないけど、WordPress Ping Optimizerプラグインがいたので消そう。以前にPingオワコンと書いておきながらプラグインを消してなかったのか……

このプラグインが遅かっただけかもしれないので、これで様子を見よう。

予約投稿の失敗対策

プラグインにリカバリーさせる

WP Missed Schedule Fix Failed Future Postsというプラグインがあって、予約投稿のもので現在時刻を過ぎてたら公開処理をする、ということをしてくれます。

wp-missed-schedule.php
  function wpms_init()
    {
      global $wpdb;

      $qry = <<<SQL

      SELECT ID FROM {$wpdb->posts} WHERE ( ( post_date > 0 && post_date <= %s ) ) AND post_status = 'future' LIMIT 0,10

SQL;

      $sql = $wpdb->prepare( $qry, current_time( 'mysql', 0 ) );

      $scheduledIDs = $wpdb->get_col( $sql );

      if ( !count( $scheduledIDs ) )
        return;

      foreach ( $scheduledIDs as $scheduledID )
        {
          if ( !$scheduledID )
            continue;

          wp_publish_post( $scheduledID );
        }
    }

このプラグインを使えば、投稿時間は後ろにずれるものの、いずれ投稿してくれます。

PHP-FPMの設定を見直す

そもそも同時リクエスト数が足りてないから問題が起こるわけで、設定の見直しは必要ですね。

こっちは別の設定と合わせてPHP-FPMの設定見直しとして記事を書く予定。