Khắc phục việc treo wordpress khi chưa kịp thực hiện các lệnh pingback hoặc trackback
Trong khi sử dung wordpress, với dữ liệu khổng lồ hằng ngày đổ vào hệ thống, kết hợp với khả năng pingback và trackback tự động của WordPress, nột điểm khá thú vị của WordPress và tốt cho SEO, nhưng cũng đem lại phiền toái không nhỏ với người quản trị hệ thống.
Vậy có vấn đề gì xảy ra, tôi không muốn nói tới việc bạn để WordPress chạy Cron Job khi người dùng truy cập website… kể cả khi bạn đã tắt tình năng này và sử dụng chạy WordPress Cron Job thủ công với crontab trên Unix (nếu bạn chưa tôi ưu hiệu xuất của wordpress theo cách này… hãy đón chờ bài viết giời thiệu tính năng này trên blog của tôi trong một vài ngày tới nhé).
Trở lại với tình huống trên, thú thật là khi chuyển đổi Server cho ứng dụng của mình, tôi đã quên bật Crontab thực hiện chức năng chạy thủ công, để thực hiện các CronJob của WordPress… nên hệ thống của tôi xảy ra tình trạng tồn đọng các lệnh pingback và trackback cần thiết phải xử lý. Tất nhiên khi tôi nhớ ra điều này thì khối lượng lệnh tồn đọng đã chiếm một số lượng rất lớn. Hệ thống của tôi trở nên ỳ ạch mỗi khi crontab thủ công kia tiến hành.
Và sau đây là đoạn mã nguồn tôi tìm được và tiến hành xử lý trong file wp-includescomment.php
function do_all_pings() {
global $wpdb;
// Do pingbacks
while ($ping = $wpdb->get_row(“SELECT ID, post_content, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = ‘_pingme’ LIMIT 1″)) { delete_metadata_by_mid( ‘post’, $ping->meta_id ); pingback( $ping->post_content, $ping->ID ); }
// Do Enclosures
while ($enclosure = $wpdb->get_row(“SELECT ID, post_content, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = ‘_encloseme’ LIMIT 1”)) { delete_metadata_by_mid( ‘post’, $enclosure->meta_id ); do_enclose( $enclosure->post_content, $enclosure->ID ); }
$trackbacks = $wpdb->get_col(“SELECT ID FROM $wpdb->posts WHERE to_ping ” AND post_status = ‘publish'”);
if ( is_array($trackbacks) )
foreach ( $trackbacks as $trackback )
do_trackbacks($trackback);
//Do Update Services/Generic Pings
generic_ping();
}
Các bạn chú ý những dòng được bôi đậm, hệ thống sẽ tiến hành thực hiện hàng trăm, ngàn câu lệnh tìm kiếm những bản ghi phù hợp, ghi nhận việc phải pingback / trackback để thực hiện… Giải pháp của tôi là bắt hệ thống xử lý dần dần với việc giới hạn lại số lượng post cần xử lý mỗi khi thực hiện… ở đây tôi lấy luôn số lượng post hiển thị ở trang chủ làm giới hạn của việc này. Thực tế nếu hệ thống của bạn chạy thường xuyên thì việc trên không dẫn đến việc nghẽn hệ thống… nhưng nếu bạn gặp trường hợp giống tôi… hi vọng bạn có thể tham khảo các xứ lý này.
function do_all_pings() {
global $wpdb;
// get limit of post per page
$limit = get_option(‘posts_per_page’, 10);
$limit = $limit * 50;
// Do pingbacks
$pings = $wpdb->get_results($wpdb->prepare(“SELECT meta_id, post_id FROM {$wpdb->postmeta} WHERE meta_key = ‘_pingme’ LIMIT %d”, $limit));
if (is_array($pings)) {
foreach ($pings as $ping) {
$post_id = $ping->post_id;
$post = get_post($post_id);
delete_metadata_by_mid( ‘post’, $ping->meta_id );
//pingback( $ping->post_content, $ping->ID );
pingback( $post->post_content, $post->ID );
}
}
$enclosures = $wpdb->get_results($wpdb->prepare(“SELECT meta_id, post_id FROM {$wpdb->postmeta} WHERE meta_key = ‘_encloseme’ LIMIT %d”, $limit));
if (is_array($enclosures)) {
foreach($enclosures as $enclosure) {
$post_id = $enclosure->post_id;
$post = get_post($post_id);
delete_metadata_by_mid( ‘post’, $enclosure->meta_id );
//do_enclose( $enclosure->post_content, $enclosure->ID );
do_enclose( $post->post_content, $post->ID );
}
}
// Do Trackbacks
$trackbacks = $wpdb->get_col($wpdb->prepare(“SELECT ID FROM $wpdb->posts WHERE to_ping ” AND post_status = ‘publish’ LIMIT %d”, $limit));
if ( is_array($trackbacks) )
foreach ( $trackbacks as $trackback )
do_trackbacks($trackback);
//Do Update Services/Generic Pings
generic_ping();
}
Chúc các bạn thành công.