Chạy WP Cron trên multisite đúng cách


18

Tôi có WordPress Multisite với một số trang web. Tôi thiết lập DISABLE_WP_CRONđể truetrong của tôi wp-config.php.

Nếu chúng ta thiết lập tác vụ cron với wget hoặc curl, chúng ta có quy tắc 30 giây để thực thi tập lệnh PHP. Thật nhỏ để gửi hàng tấn thông báo email và thực hiện các công việc khác (có thể kết nối máy chủ SMTP từ xa chậm, có thể đó là một loạt thông báo email thực sự lớn từ bbPress hoặc bất cứ điều gì).

Có lẽ chúng ta có thể sử dụng một cái gì đó như thế này?

php -q wp-cron.php

Nhưng nó chỉ chạy cron đến một trang trong Multisite (mỗi trang có các tác vụ cron riêng trong các bảng MySQL khác nhau).

PS Trên diễn đàn wpmudev.org tôi tìm thấy "giải pháp" lạ cũng sử dụng Curl.

Một PS WP CLI khác có wp croncác lệnh tuyệt vời nhưng nó chỉ cho phép chạy các tác vụ cron bằng tay (vâng, chúng ta có thể sử dụng --urlattr). Ví dụ:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com

Bạn đã xem WP-CLImã cốt lõi chưa?
kaiser

Vâng. Tôi đào sâu vào mã nguồn ngay bây giờ và cố gắng hiểu :) Lệnh để chạy tất cả các tác vụ (sự kiện) không tồn tại, có lẽ tôi có thể tạo nó trong tương lai.
Kolya Korobochkin

Bạn có wp/ WP-CLI trong bạn PATHkhông? Nếu có, tại sao không kích hoạt nó từ một tệp bash chạy trong cron?
kaiser

Âm thanh tuyệt vời! Nhưng làm thế nào để chạy tất cả các tác vụ cron từ wp cli? Tôi không thấy bất kỳ lệnh nào cho việc này.
Kolya Korobochkin

Chính xác như bạn đã thể hiện ở cuối câu hỏi của bạn?
kaiser

Câu trả lời:


13

Tôi nghĩ cách tốt nhất là sử dụng WP-CLI nhưng bạn cần viết một tập lệnh bash để làm điều này. Đây là một cái nên làm cho bạn:

WP_PATH="/path/to/wp"
for SITE_URL in = $(wp site list --fields=domain,path,archived,deleted --format=csv --path="$WP_PATH" | grep ",0,0$" | awk -F ',' '{print $1 $2}')
do
    for EVENT_HOOK in $(wp cron event list --format=csv --fields=hook,next_run_relative --url="$SITE_URL" --path="$WP_PATH" | grep \"now\"$ | awk -F ',' '{print $1}')
    do
        wp cron event run "$EVENT_HOOK" --url="$SITE_URL" --path="$WP_PATH"
    done
done

Sau đó, bạn cần thêm tập lệnh này vào crontab và chạy nó có thể mỗi phút nếu bạn muốn


Tôi cảm ơn vì ý kiến ​​của bạn nhưng tôi nghĩ đây là giải pháp hacky (bẩn). Tôi nghĩ sẽ tốt hơn khi viết một số addon PHP cho wpcli để chạy tất cả các tác vụ cần thiết. Tôi cần thêm thời gian để hiểu các chức năng và mã WP để làm điều đó.
Kolya Korobochkin

4
@KolyaKorobochkin Tôi không đồng ý. Điều này hoàn toàn không phải là hack vì WP CLI đã được tạo ra để được sử dụng trên dòng lệnh và trong các tập lệnh bash.
DiverseAndRemote.com

1
wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH- Theo các runtài liệu, bạn nên sử dụng --due-nowcờ. Điều này sẽ làm giảm việc tra cứu và các cuộc gọi sự kiện cá nhân. Xem: wp-cli.org/commands/cron/event/run . Dù bằng cách nào, tôi với @OmarJackman - anh ấy đang sử dụng dòng lệnh để sử dụng các công cụ dòng lệnh WordPress. Đạo cụ cho một ví dụ Bash sạch. Bạn có thể làm tròn câu trả lời này bằng cách hiển thị mục crontab.
jgraup

Vì lợi ích của độc giả trong tương lai, kịch bản sau đó trông giống như:WP_PATH="/path/to/wp"; for SITE_URL in $(wp site list --fields=domain,path,archived,deleted --format=csv --path="$WP_PATH" | grep ",0,0$" | awk -F ',' '{print $1 $2}'); do wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH"; done
bối rối

10

Sau khi bạn thêm hằng số vào wp-config.php

defined('DISABLE_WP_CRON') or define('DISABLE_WP_CRON', true);

WP-CLI

Và giả sử bạn đã config.ymlthiết lập chính xác, bạn có thể tắt --pathcờ khi gọi cron run.


wp cron event run --due-now

[<hook>…] Một hoặc nhiều móc để chạy.

[--due-now] Chạy tất cả các móc do ngay bây giờ.

[--all] Chạy tất cả các móc.


Để chạy tất cả các tác vụ cron theo thứ tự:

function run_crons_due_now_in_order { for SITE_URL in $(wp site list --fields=url --format=csv | tail -n +2 | sort); do wp cron event run --due-now --url="$SITE_URL" && echo -e "\t+ Finished crons for $SITE_URL"; done; echo "Done"; }; run_crons_due_now_in_order;

Nếu bạn muốn chúng chạy đồng thời (trước tiên hãy chạy cron không dành riêng cho trang web):

function run_all_crons_due_now { for SITE_URL in $(wp site list --fields=url --format=csv | tail -n +2 | sort); do wp cron event run --due-now --url="$SITE_URL" && echo -e "\t+ Finished crons for $SITE_URL" & done; wait $(jobs -p); echo "Done"; }; run_all_crons_due_now;

Bạn sẽ muốn đặt một trong hai tùy chọn trong một tập tin thực thi

chmod +x run_all_wp_cron_events_due_now.sh

thêm một nhiệm vụ crontab

crontab -e

và có thể thực hiện mỗi phút

* * * * * run_all_wp_cron_events_due_now.sh > /dev/null

Nếu bạn muốn chạy một lệnh tùy chỉnh từ cron, bạn có thể cần chỉ định các đường dẫn đầy đủ để wp-cli hoạt động.

* * * * * cd /home/username/public_html; /usr/local/bin/php /home/username/wp-cli.phar your-custom-cron-commands run >/dev/null 2>&1

PHP

Lý do duy nhất bạn cần tải lên WordPress ở đây là để thu thập các URL từ cơ sở dữ liệu thay vì sử dụng danh sách được xác định trước. Chúng tôi sẽ chỉ ping các URL đó và chúng tôi không thực sự quan tâm phản hồi là gì.

custom-cron.php

<?php

// Load WP
require_once( dirname( __FILE__ ) . '/wp-load.php' );

// Check Version
global $wp_version;
$gt_4_6 = version_compare( $wp_version, '4.6.0', '>=' );

// Get Blogs
$args  = array( 'archived' => 0, 'deleted' => 0, 'public' => 1 );
$blogs = $gt_4_6 ? get_sites( $args ) : @wp_get_sites( $args ); // >= 4.6

// Run Cron on each blog
echo "Running Crons: " . PHP_EOL;
$agent = 'WordPress/' . $wp_version . '; ' . home_url();
$time  = time();

foreach ( $blogs as $blog ) {
    $domain  = $gt_4_6 ? $blog->domain : $blog['domain'];
    $path    = $gt_4_6 ? $blog->path : $blog['path'];
    $command = "http://" . $domain . ( $path ? $path : '/' ) . 'wp-cron.php?doing_wp_cron=' . $time . '&ver=' . $wp_version;

    $ch = curl_init( $command );
    $rc = curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
    $rc = curl_exec( $ch );
    curl_close( $ch );

    print_r( $rc );
    print_r( "\t✔ " . $command . PHP_EOL );
}

Và thêm một cuộc gọi custom-cron.phpvào crontab của bạn

* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron

1

Một lớp lót dễ dàng hơn với ít bash:

wp site list --field=url | xargs -i -n1 wp cron event run --due-now --url="{}"

Bạn có thể chạy thủ công hoặc đặt nó vào một tập lệnh và gọi nó từ cron như trong các câu trả lời khác.


0

Đây là giải pháp của tôi:

global $multisite_hosts;
$multisite_hosts = Array('xxxx.dev.xxx.oondeo.es','x2.dev.xxx.oondeo.es','x3.dev.xxx.oondeo.es');

function run_cron(){
  global $multisite_hosts;
  $host=array_pop($multisite_hosts);
  if (!$host)
    return;
  register_shutdown_function('shutdown');
  if (!isset($_SERVER['HTTP_HOST'])) {
       $_SERVER['HTTP_HOST'] = $host;  // replace with primary host
  }

  require './wp-cron.php';
}

function shutdown()
{
  run_cron();
}
run_cron();

Chúng tôi gọi nó từ crontab, hy vọng nó sẽ giúp


-5

Tôi nghĩ rằng bạn cần cho chúng tôi biết ý của bạn bằng cách "chạy wp-cron.php đúng cách" trước hết. Theo Wordpress, không có nghĩa là bạn vô hiệu hóa wp-cron mà vẫn muốn nó chạy ... Từ quan điểm của Linux, wget-ing hoặc / bin / php-ing wp-cron.php sẽ đúng, nhưng Có vẻ như máy chủ lưu trữ cụ thể của bạn đang giới hạn số lượng yêu cầu php của bạn vì lý do bảo mật? - phần đó không hoàn toàn rõ ràng từ mô tả của bạn.

Một câu hỏi khác: có bao nhiêu email là "một tấn"? Có nhiều lý do tuyệt vời khiến bạn không nên cố gắng gửi quá nhiều email nhanh chóng.

Bạn có thể phải suy nghĩ lại mục tiêu của bạn.

(Tôi sẽ bình luận thay vì trả lời nhưng tôi không có đủ danh tiếng trên wpstack.)


3
Có nhiều cách để chạy cron WordPress. Cơ chế tích hợp được kích hoạt bởi các lượt xem trang và thông thường, nó được thiết lập DISABLE_WP_CRONđể tắt phương thức này khi thiết lập phương thức cron hệ thống đáng tin cậy hơn thay thế.
Marcus Downing

Câu hỏi đặt ra không phải là lý do tại sao phải làm điều đó / nếu những lý do có ý nghĩa nhưng cách gọi một cách chính xác wp-cron.php trên một cài đặt cho nhiều. Khá rõ ràng đối với tôi;)
Philipp

1
Tôi hy vọng bạn nhận ra bạn đang bình luận về một câu trả lời rất cũ và đã bị ẩn.
Jorge Orpinel
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.