2013年6月18日星期二

Missed Schedule on scheduled posts because of crons and transient data

Many people still have issues about (not so) future posts going live. When the target date hits, its goes red, says "Missed Schedule" and continues on without it.
There are other issues that may be showing up on the box such as an enormous call back log (>1,000,000 hits/day from its own IP to wp-crons.php). Cache clean up failings, and other background routines fail.

I have spent the last week tracking this down on numerous servers and have this list of routines to fix it:

Is the server cognizant of its own domain? WordPress curls out to "http://yourdomain.com/wp-cron.php..." If the server is not configured to know its own domain and IP address of yourdomain.com' the self call to the cron will fail.
Some servers are behind a firewall that doesn't allow traffic to echo back. Meaning, it knows yourdmain.com = an.ip.addr.ess and sends a connection out through the firewall... which then doesn't come back in. The firewall must be configured to know that an.ip.addr.ess is internal and it must echo it back to the source machine.
Of course curl must be enabled and installrf in PHP so check php.ini for extension=php_curl.dll
Easiest way to check is to review the logs and see if there are calls to your /wp-cron.php file. If there is not, the cron mechanism can't call itself.

you can by-pass some of these in the wp-config.php with:
define('ALTERNATE_WP_CRON', true);

------------------------------

if that doesn't fix your problem or your log file shows hits to wp-cron.php... in fact its flooding your logs and adding unnecessary strain to your server then its an internal cron failure.

program errors: Are there errors in the log file indicating that a function that is called by the cron is failing? If so the cron job never completes, never gets unschedule, and is subsequently called repeatedly without completetion. Fix the error!
W3 Cache. If any site establishes an object cache, object-cache.php gets written to /wp-content/. This turns object caching on for all sites, whether they are configured or not. If the cron detects that object caching is on, it stores the cron id/task in the obj-cache to be passed around instead of the DB transient data. When the cache is not working your cron key to run the job is being tossed to the wind. After /wp-cron.php starts and gets an empty transient it will exit, leaving the task unprocessed in the queue and results in wp-cron being called repeatedly.
in the /wp-cron.php, you can log the value of $doing_cron_transient = get_transient( 'doing_cron'); and see what the cron task is getting.
If its empty, your cron keys are being tossed.

Look for /wp-content/object-cache.php. If its there, all sites are running as object cached even if they are not configured. configure all the sites to use it properly.
Or rename object-cache.php ... that will remove object caching from all sites, which could break the initiating offender, but restore cron operations and transient data to all other sites.

If its the object caching on the set_transient/get_transient calls, then more than just the cron jobs and schedule posts are failing.

Look through error logs for 'cron' and 'wp-cron' as the called URI or in the stack trace.

to by-pass the object-cache issue you can modify the wp-cron.php to:

if ( empty( $doing_wp_cron ) ) {
        if ( empty( $_GET[ 'doing_wp_cron' ] ) ) {
                if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $local_time ) ){
                        return;
                }
                $doing_cron_transient = $doing_wp_cron = time();
                set_transient( 'doing_cron', $doing_wp_cron );
        } else {
                $doing_wp_cron = $_GET[ 'doing_wp_cron' ];
                if($_GET[ 'flush' ])  //ADDED
                  $doing_cron_transient = $doing_wp_cron; //ADDED
        }
}


then OS level cron a call to $time = time()
http://yourdomain(s).com/wp-cron.php?doing_wp_cron=$time&flush=1
every 5 minutes.

This will cause the cron to continue without the transient ID and resolve back-logged tasks within an hour.

没有评论:

发表评论