WP Cron không thực thi khi thời gian trôi qua


16

Mục đích

Tôi muốn sử dụng wp_schedule_single_event( )để thực thi một sự kiện duy nhất gửi cho tôi e-mail 8 phút sau khi người dùng gửi biểu mẫu.

Vấn đề

Các mã sau đây là trong của tôi functions.php:

function nkapi_send_to_system( $args ) {
  wp_mail( 'xxx', 'xxx', $args );
}

add_action( 'nkapi_send', 'nkapi_send_to_system' );

function schedule_event( $id ) {
  wp_schedule_single_event( current_time( 'timestamp' ) + 480, 'nkapi_send', array( $id ) );
}

Và đoạn mã sau được sử dụng để gọi schedule-event:

schedule_event( $_SESSION['insert_id'] ); // the $_SESSION var contains an INT

Sau khi chờ đợi hơn 8 phút, không có e-mail trong hộp thư đến của tôi.

Những gì tôi đã cố gắng

Với plugin Core Control , có thể thấy các công việc định kỳ được lên lịch.

Màn hình điều khiển lõi

Sau một vài thay đổi, tôi đã xoay sở để có được chúng khá chính xác và tốt hơn, khi tôi nhấn "Chạy ngay", tôi thực sự nhận được một e-mail trong hộp thư đến của mình.

Nhưng tại sao cron's không thực thi khi tôi truy cập trang web của mình sau 8 phút. Điều gì có thể là sai với mã này? Tôi phải nói rằng đây là lần đầu tiên tôi sử dụng WP Cron.

Tôi đã cố gắng nhiều hơn

Sau khi nhận xét về id vancoder đã quyết định kiểm tra xem mã có hoạt động không nếu tôi đặt mã sau đây trực tiếp vào functions.php:

function schedule_event( $id ) {
  wp_schedule_single_event( time(), 'nkapi_send', array( $id ) );
}

if ( isset( $_SESSION['insert_id'] ) ) {
  if ( ! array_key_exists( 'insert_scheduled', $_SESSION ) || $_SESSION['insert_scheduled'] != $_SESSION['insert_id'] ) {
    schedule_event( $_SESSION['insert_id'] );
    $_SESSION['insert_scheduled'] = $_SESSION['insert_id'];
  }
}

Nhược điểm của mã này là, người dùng phải chuyển sang trang khác trước khi mã này được thực thi. Nhưng mặt khác, điều này cũng không hoạt động nên đó không phải là vấn đề đầu tiên của tôi ...


1
schedule_event( $_SESSION['insert_id'] );Bị sa thải ở đâu và như thế nào ?
vancoder

Một shortcode bao gồm một tệp riêng biệt (có một biểu mẫu trong đó) trong một trang, khi biểu mẫu đó được đăng tải lại trang, cùng một tệp sau đó thực thi schedule_event( ), giả sử ở trên cùng của tệp được bao gồm bởi shortcode.
Mike Madern

bất kỳ crons làm việc? wp_version_check vv?
vancoder

Tôi đã không nhận được bất kỳ crons để làm việc. Điều gì có thể là vấn đề của điều đó?
Mike Madern

Để xác nhận - ngay cả công việc cron cốt lõi thất bại?
vancoder

Câu trả lời:


8

Trước tiên, bạn có thể vui lòng xác nhận rằng bạn không kích hoạt bất kỳ plugin nào không? Các plugin lưu đệm có thể can thiệp vào các công việc định kỳ vì khách truy cập của bạn không được phục vụ một trang trực tiếp mà là một phiên bản được lưu trong bộ nhớ cache của trang của bạn.

Nếu bạn đã bật plugin bộ nhớ đệm, bạn có thể chọn một trong các trang của mình, thêm dấu chấm than vào cài đặt của bộ đệm ẩn cho trang đó để trang đó không bao giờ bị lưu.

Sau đó, bạn sẽ phải tự tạo một công việc định kỳ (sử dụng cpanel nếu bạn đang ở trong môi trường lưu trữ được chia sẻ hoặc từ thiết bị đầu cuối nếu đó là VPS / máy chủ chuyên dụng) sẽ truy cập trang đó cứ sau vài phút.

Tôi hy vọng điều đó sẽ giúp!


Tôi đã kích hoạt một bộ đệm ẩn! Chính xác là W3 Total Cache
Mike Madern

14

Đầu tiên, xác định lịch trình công việc cron tùy chỉnh của bạn.

add_filter('cron_schedules', array($this, 'cron_schedules'));

public function cron_schedules($schedules){
    $prefix = 'cron_';// Avoid conflict with other crons. Example Reference: cron_30_mins
    $schedule_options = array(
        '30_mins' => array(
            'display' => '30 Minutes',
            'interval' => '1800'
        ),
        '1_hours' => array(
            'display' => 'Hour',
            'interval' => '3600'
        ),
        '2_hours' => array(
            'display' => '2 Hours',
            'interval' => '7200'
        )
    );
    /* Add each custom schedule into the cron job system. */
    foreach($schedule_options as $schedule_key => $schedule){
        $schedules[$prefix.$schedule_key] = array(
            'interval' => $schedule['interval'],
            'display' => __('Every '.$schedule['display'])
        );
     }
     return $schedules;
}

Bạn cần phải quyết định nơi và khi nào thực sự lên lịch sự kiện.

Đây chỉ là một đoạn mã ví dụ, thực hiện cuộc gọi đến một phương thức lớp tùy chỉnh:

$schedule = $this->schedule_task(array(
    'timestamp' => current_time('timestamp'), // Determine when to schedule the task.
    'recurrence' => 'cron_30_mins',// Pick one of the schedules set earlier.
    'hook' => 'custom_imap_import'// Set the name of your cron task.
));

Đây là mã thực sự lên lịch sự kiện:

private function schedule_task($task){
    /* Must have task information. */
    if(!$task){
        return false;
    }
    /* Set list of required task keys. */
    $required_keys = array(
        'timestamp',
        'recurrence',
        'hook'
    );
    /* Verify the necessary task information exists. */
    $missing_keys = array();
    foreach($required_keys as $key){
        if(!array_key_exists($key, $task)){
            $missing_keys[] = $key;
        }
    }
    /* Check for missing keys. */
    if(!empty($missing_keys)){
        return false;
    }
    /* Task must not already be scheduled. */
    if(wp_next_scheduled($task['hook'])){
        wp_clear_scheduled_hook($task['hook']);
    }
    /* Schedule the task to run. */
    wp_schedule_event($task['timestamp'], $task['recurrence'], $task['hook']);
    return true;
}

Bây giờ, tất cả những gì bạn cần làm là thực hiện một cuộc gọi đến tên của tác vụ cron tùy chỉnh của bạn. Trong ví dụ này, tên tác vụ cron là custom_imap_import.

add_action('custom_imap_import', array($this, 'do_imap_import'));

public function do_imap_import(){
    // .... Do stuff when cron is fired ....
}

Vì vậy, trong ví dụ này, $this->do_imap_import();được gọi cứ sau 30 phút (giả sử bạn có đủ lưu lượng truy cập vào trang web của mình).


Ghi chú

Yêu cầu truy cập trang để cron của bạn bắn vào đúng thời điểm.

Ví dụ: Nếu bạn lên lịch một nhiệm vụ trong khoảng thời gian 30 phút, nhưng không ai truy cập trang web của bạn trong 4 giờ, công việc định kỳ của bạn sẽ không bị sa thải cho đến khi khách truy cập đến trang web của bạn 4 giờ sau đó. Nếu bạn thực sự cần nhiệm vụ của mình bị sa thải cứ sau 30 phút, thì bạn nên thiết lập một công việc định kỳ hợp pháp thông qua nhà cung cấp dịch vụ lưu trữ web để truy cập trang web của bạn theo các khoảng thời gian mong muốn.

Công việc cron WordPress không làm cho trang web của bạn chậm!

Có thể bạn đang nghĩ nếu kịch bản cron mất nhiều thời gian để được thực thi thì khách truy cập sẽ phải đợi cho đến khi tập lệnh được thực thi. Không! Không thể nào? Nếu bạn nhìn vào wp-cron.phptập tin, bạn sẽ tìm thấy một dòng

ignore_user_abort(true);

Đó là một php.inicấu hình đặt ra rằng nếu bạn dừng tải trang web / tập lệnh thì tập lệnh sẽ không dừng thực thi.

Nếu bạn nhìn vào wp-includes/cron.phptập tin, bạn sẽ tìm thấy một dòng như thế này:

wp_remote_post( $cron_url, 
array('timeout' => 0.01,
 'blocking' => false, 
 'sslverify' => apply_filters('https_local_ssl_verify', true)) );

Điều đó có nghĩa WordPress sẽ đợi chỉ 0,01 giây để kích hoạt việc thực hiện sau đó nó sẽ hủy bỏ nhưng khi bạn đã thiết lập ignore_user_abortđể truekịch bản sẽ được thực hiện. Chức năng này là một lợi thế rất lớn để thực thi các tập lệnh lớn trong các công việc định kỳ WordPress.

Chức năng có sẵn để hỗ trợ:


6
Đây là một câu trả lời toàn diện đáng chú ý, theo như tôi có thể thấy, không giải quyết được câu hỏi thực tế - đó là lý do tại sao tất cả các nhiệm vụ theo lịch trình (bao gồm các nhiệm vụ cốt lõi) đều thất bại.
vancoder

Câu trả lời này là hướng dẫn người dùng đi đúng hướng để hiểu và lên lịch chính xác cho các tác vụ cron WordPress.
Michael Ecklund

4
Điều này chắc chắn đã giúp tôi hiểu rất nhiều về lịch trình cron với WordPress
Mike Madern

2
Michael, bạn nên trả lời thường xuyên hơn. Tuyệt vời +1
kaiser

1
Tôi nghĩ rằng WP_Cronsử dụng GMT dưới mui xe, giống như phần còn lại của WP, vì vậy tốt hơn là lên lịch cho sự kiện đầu tiên time()thay vì current_time().
Ian Dunn

3

WordPress Cron cho phép bạn lên lịch các tác vụ, nhưng chúng sẽ chỉ thực hiện nếu có yêu cầu được thực hiện cho trang web. Đối với mỗi yêu cầu mà WordPress nhận được, nó sẽ kiểm tra xem có xử lý các công việc định kỳ hay không và nếu có thì yêu cầu /wp-cron.php?doing_wp_cronkhông đồng bộ để xử lý công việc. Nếu bắt đầu theo lịch trình của một công việc mà không có yêu cầu, thì quá trình cron sẽ không được bắt đầu.

Vì bạn có thể xem và chạy các công việc đã lên lịch của mình, có thể không có yêu cầu nào kích hoạt công việc định kỳ để bắt đầu, đặc biệt nếu bạn đang sử dụng plugin lưu trữ. Tùy chọn tốt nhất để giảm tải cho lịch trình thường xuyên hơn là vô hiệu hóa kiểm tra mặc định trong WordPress và sử dụng crontab.

Trước tiên để vô hiệu hóa kiểm tra mặc định (có thể giúp một chút với hiệu suất phía máy khách), hãy thêm các mục sau vào wp-config.php:

// Disable default check for WordPress cron jobs on page loads
define( 'DISABLE_WP_CRON', true );

Tiếp theo, bạn tạo một tác vụ để tìm nạp wp-cron.phptrang một lần một phút để xử lý bất kỳ công việc nào ở mặt sau, từ dòng lệnh nhập crontab -evà sau đó thêm một dòng giống như sau:

*/1 * * * * /usr/bin/curl --silent http://example.com/wp-cron.php?doing_wp_cron=$(date +\%s.\%N) >/dev/null 

2
Nếu bạn không cung cấp giá trị doing_wp_cron, điều này rất có thể khiến các công việc đôi khi được thực thi hai lần. Sử dụng doing_wp_cron=$(date +\%s.\%N)để ngăn chặn điều đó.
Vườn Alexander

0

Kiểm tra xem DISABLE_WP_CRON không được đặt trong cấu hình của bạn.

Không, hãy thử vô hiệu hóa tất cả các plugin (ngoại trừ kiểm soát lõi - mặc dù tôi sẽ sử dụng wp-crontrol) và xem công việc cốt lõi của bạn có hoạt động không. Nếu họ làm như vậy, bạn đang gặp phải sự can thiệp của plugin ở đâu đó.

Tương tự, hãy thử chuyển sang một chủ đề thứ hai mươi tiêu chuẩn.

Nếu không ai trong số này tạo ra bất kỳ sự khác biệt nào, rất có thể đó là vấn đề lưu trữ.


Tôi không DISABLE_WP_CRONđặt ra wp-config.php, tôi sẽ thử nhiều thứ hơn và quay lại sau
Mike Madern

0

Kiểm tra bất kỳ plugin nào ẩn Wordpress.

Làm thế nào để xem nếu đây là vấn đề?

  1. Điều hướng đến http (s): //yoursite.com/wp-cron.php Bạn sẽ thấy một trang trống. Một cái hoàn toàn trống rỗng.
  2. Bên cạnh đó, bạn phải thấy trong trình quản lý công việc định kỳ một lần trong "Thực thi tiếp theo": Công việc định kỳ được lên lịch - nếu wp-cron.php hoạt động đúng (không chỉ văn bản "Trong hàng đợi" - mà là một thời gian nhất định - đối với một số mục "Trong hàng đợi" đôi khi vẫn ổn, nhưng nếu đó là điều duy nhất bạn thấy -> cron của bạn không hoạt động.)

+1. Không tin bất kỳ plugin nào "kiểm tra xem cron có hoạt động không" - ví dụ: plugin kiểm tra trạng thái WP Cron đã cho thấy cron đang hoạt động. Nhưng thực tế thì không. Bất cứ điều gì nó hiển thị - tin vào mắt bạn và không phải plugin này!

Kết luận: Nếu đó là lỗi 404 - thì hãy tắt a) không chỉ các bộ đệm ẩn như những người khác đề xuất b) mà còn bất kỳ plugin nào ẩn Wordpress.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.