Hoàng Web

Thiết Kế Website WordPress

  • Kho giao diện
  • Dịch Vụ
    • Thiết kế web giá rẻ
    • Thiết kế website WordPress
    • Hosting Miễn Phí 100GB
    • Tích hợp thanh toán MoMo, ViettelPay, Vietcombank, MB..
    • Tối ưu Google PageSpeed
    • Sửa lỗi nâng cấp website
    • Viết plugin WordPress
    • Code Tool theo yêu cầu
  • Bảng giá
  • Quy trình làm việc
  • Giới thiệu
  • Liên Lạc
Trang chủ » Thủ thuật » Sử lý tác vụ nền (Queue Jobs Non-Blocking) trong WordPress

Sử lý tác vụ nền (Queue Jobs Non-Blocking) trong WordPress

Thứ Tư, 20/03/2019 by Hoàng Quách

Nội dung

  • 1 Tác vụ & Hàng đợi
  • 2 Một minh chứng khác
  • 3 Lỗi PHP khi sử lý với dữ liệu lớn
  • 4 Sử dụng tác vụ nền
  • shares
  • Facebook
  • Facebook Messenger
  • Gmail
  • Viber
  • Skype

Trong bài trước mình có hướng dẫn các bạn tối ưu CRON Job trong WordPress. Hôm nay mình sẽ nói về công nghệ mới liên quan đến sử lý tác vụ nền. Một tác vụ nặng cần nhiều thời gian sử lý hơn và cần chạy ở tác vụ nền. Nếu bạn quan tâm kỹ thuật này, hãy đọc tiếp bài này nhé.

Ưu điểm của tác vụ nền

  • tab trình duyệt không cần mở cho đến khi tác vụ kết thúc.
  • kỹ thuật này sẽ làm server không bị quá tải khi sử lý mã PHP

Theo mặc định các tasks được lưu trong database, tuy nhiên bạn có thể sử dụng Redis. Thư viện này gồm 2 phần: Async Request & Background Process (sử lý nhiều tasks được lưu trong hàng đợi).

Nếu máy chủ có nhiều tài nguyên hơn, những hàng đợi đó sẽ chạy nhiều công việc hơn mỗi đợt so với một máy chủ có ít tài nguyên hơn. Và bạn có thể thêm nhiều tasks vào hàng đợi để nó sử dần.

Cài đặt thư viện thông qua composer.

composer require a5hleyrich/wp-background-processing

Tác vụ & Hàng đợi

Chúng ta cần tạo một class kế thừa class WP_Background_Process. Ví dụ:

class BackgroundProcessExample extends WP_Background_Process {

	protected $action = 'florianbrinkmann_background_process';

	/**
	 * Task
	 *
	 * Override this method to perform any actions required on each
	 * queue item. Return the modified item for further processing
	 * in the next pass through. Or, return false to remove the
	 * item from the queue.
	 *
	 * @param mixed $item Queue item to iterate over
	 *
	 * @return mixed
	 */
	protected function task( $item ) {
		error_log( $item );

		sleep( 5 );

		return false;
	}

	/**
	 * Complete
	 *
	 * Override if applicable, but ensure that the below actions are
	 * performed, or, call parent::complete().
	 */
	protected function complete() {
		parent::complete();
	}
}

Trong đó:

  • protected $action tên nhận dạng duy nhất, ID này sẽ xác định mỗi nhóm các tasks
  • function task( $item ) sử lý mỗi task từ hàng đợi. Ví dụ đơn giản trên, mình lưu task vào tệp log và tạm dừng script 5s. Nếu hàm trả về false , task sẽ được xóa khỏi hàng đợi. Ngược lại, giá trị trả về sẽ được sử dụng trong các tác sau.
  • function complete() chứa hành động sau khi tác vụ nền sử lý xong, vd gửi email thông báo. Lưu ý: cần gọi parent::complete() để xác nhận task đã sử lý hoàn tất.

Để chạy tác vụ này bạn sử dụng đoạn code sau:

$background_process = new BackgroundProcessExample();

// Add items to the queue.
$counter = 0;
do {
	$counter ++;
	$background_process->push_to_queue( $counter );
} while ( $counter < 10 );

// Start the queue.
$background_process->save()->dispatch();

Ví dụ trên, mình chạy vòng lặp với nội dung task thêm vào hàng đợi khác nhau bởi $counter. Để bắt đầu chạy tác vụ nền chúng ta gọi $background_process->save()->dispatch()

Nếu bạn chạy tập lệnh này và sau đó xem nhật ký lỗi của bạn (không phải ngay lập tức, vì độ trễ năm giây cho mỗi lần), bạn sẽ thấy các số từ 1 đến 10 trong khoảng thời gian 5 giây. Tuy nhiên, việc tải trang để chạy tập lệnh không cần mất 50 giây, vì tác vụ đã được xử lý ở chế độ nền.

Một minh chứng khác

Đặt dữ liệu danh sách vào một CSV có thể tải xuống và lưu trữ tất cả các hình ảnh thông qua FTP. Điều này đã không thay đổi trong nhiều năm và có khả năng sẽ không thay đổi trong tương lai gần nếu không có một cuộc đại tu về công nghệ web.

Do hạn chế về công nghệ này, để kết nối các hệ thống quản lý nội dung hiện đại như WordPress với thông tin này, chúng ta có thể viết plugin WordPress kéo dữ liệu CSV, xử lý và nhập dưới dạng bài đăng. Các hình ảnh có thể được lấy thông qua PHP Curl và được lưu trữ trong media. Tuy nhiên, Vấn đề kết nối tài nguyên bạn phải chờ đợi khi quá trình hoàn tất.

Vấn đề khi việc chờ đợi máy chủ web sử lý thường bị giới hạn về thời gian (đôi khi 30 giây, dài hơn hoặc ngắn hơn tùy thuộc vào cấu hình. Chú ý: Bạn cũng có thể tăng thời gian thực thi PHP).

Làm thế nào bạn sẽ đối phó với loại tắc nghẽn này? Lúc này, bạn sẽ nghĩ đến chạy một tác vụ ngầm (gọi là backround job), lý tưởng là chạy đồng thời với các tác vụ khác.

Mình có tìm ra một thư viện, cho phép bạn chạy các tác vụ đồng thời cùng lúc mà không phải chờ đợi. Tải tại đây.

Lỗi PHP khi sử lý với dữ liệu lớn

Xem ví dụ sau, hàm PHP sử dụng CURL để tải ảnh.

function treb_get_images($remote_url, $remote_user, $remote_pass, $local_file) {
        try {
                $ch = curl_init();
                $fp = fopen($local_file, 'w');
                curl_setopt_array( $ch, array(
                        CURLOPT_URL => $remote_url,
                        CURLOPT_HEADER => 0,
                        CURLOPT_VERBOSE => 0,
                        CURLOPT_RETURNTRANSFER => 1,
                        CURLOPT_BINARYTRANSFER => 1,
                        CURLOPT_CONNECTTIMEOUT => 140,
                        CURLOPT_TIMEOUT => 300,
                        CURLOPT_NOSIGNAL => 1,
                        CURLOPT_FILE => $fp
                        )
                );
                // Set CURL to write to disk
                // Execute download
                $response = curl_exec($ch);
                if (FALSE === $response) {
                        throw new Exception(curl_error($ch), curl_errno($ch));
                }
        } catch(Exception $e) {
                trigger_error(sprintf(
                'Curl failed with error #%d: %s',
                $e->getCode(), $e->getMessage()),
                E_USER_ERROR);
        }
                curl_close($ch);
                fclose($fp);
}

Khi chạy code trên đôi khi bạn gặp lỗi “exceeded allocated maximum_execution_time”. Trường hợp này bạn cần sửa file php.ini (cấu hình PHP).

Sử dụng tác vụ nền

Truy cập & tải project WP Background Processing để áp dụng cho dự án WordPress của bạn. Tiếp đó, chúng ta tạo hàm để sử lý tác vụ nặng (long time). Mình sử dụng hook ‘init’.

add_action( 'init', 'process_handler' );
function process_handler() {
        $treb_import = new StdClass;
        $treb_import->treb_import_process = new Treb_Import_Process();

        if ( 'treb_images' === $_GET['process'] ) {
                // Parse date , otherwise assign current date
                if ($_GET['date']) {
                        $date = explode("-", $_GET['date']);
                } else {
                        $date = explode("-", date('d-m-Y'));
                }
                $treb_data = treb_get_csv($date);
                $loop_count = 0;
                foreach ($treb_data as $item) {
                        $loop_count++;
                        // Prep multidimensional array
                        $item_array = array(
                                        count($treb_data),
                                        $item,
                                        $loop_count
                                        );
                        // Queue the import
                        $treb_import->treb_import_process->push_to_queue($item_array);

                }
                $treb_import->treb_import_process->save()->dispatch();
        }
}

Bạn đang thắc mắc, hàm trên làm những công việc gì? những gì bạn cần làm là chú ý tới dòng code này:

$treb_import = new StdClass;
$treb_import->treb_import_process = new Treb_Import_Process();
$treb_import->treb_import_process->push_to_queue($item_array);
$treb_import->treb_import_process->save()->dispatch();

2 dòng đầu tiên sẽ khởi tạo lớp class. Dòng thứ 3 chúng ta sẽ đưa job vào hàng đợi (ví dụ trên là liệt kê dữ liệu).

Hy vọng rằng bây giờ bạn sẽ thấy những lợi ích của công nghệ này. Các tác vụ cần nhiều thời gian để sử lý (tác vụ nặng) có thể được chạy an toàn trên nền ẩn và Quá trình nền sẽ chạy từng công việc theo từng đợt nhỏ cho đến khi công việc được coi là hoàn thành. Điều này hoàn toàn độc lập với bất kỳ cài đặt máy chủ nào như max_exectuion_time.

Mọi chi tiết, vui lòng truy cập github project.

Nếu bạn thích bài viết này, hãy ủng hộ chúng tôi bằng cách đăng ký nhận bài viết mới ở bên dưới và đừng quên chia sẻ kiến thức này với bạn bè của bạn nhé. Bạn cũng có thể theo dõi blog này trên Twitter và Facebook

  • shares
  • Facebook
  • Facebook Messenger
  • Gmail
  • Viber
  • Skype

Chuyên mục: Thủ thuật Tìm kiếm: background job

Comments

  1. Best cook books says

    Thứ Năm, 21/03/2019 at 12:17 chiều

    Xin chào ngài !! Cảm ơn đã chia sẻ !! Người yêu thích của bạn Bạn !!

  2. shrey jack says

    Thứ Tư, 27/03/2019 at 8:58 chiều

    Plugin nào được sử dụng để giảm thời gian tải blog của tôi

  3. technical dadaji says

    Thứ Năm, 28/03/2019 at 4:47 chiều

    Làm thế nào chúng ta có thể làm trên trang web của mình rằng người dùng đầu tiên cần phải làm gì đó như đăng ký kênh youtube và dán thêm url id đơn vị sau đó liên kết sẽ bỏ chặn để người dùng có được liên kết bỏ chặn mà họ đang tìm kiếm … Làm thế nào chúng ta có thể làm điều này?

Tôi giúp gì cho bạn?

HOÀNG WEB

Địa chỉ: Tây Sơn, Phường Quang Trung, Quận Đống Đa, Hà Nội

Hotline: 0987 342 124 – 0868 292 303 (8h:00 – 21h:00)

Email: [email protected]

Website: www.hoangweb.com

KẾT NỐI VỚI TÔI

  • Facebook
  • GitHub
  • YouTube

SẢN PHẨM

  • Plugin Thanh Toán Quét Mã QR Code Tự Động
  • WP2Speed – Tối ưu Google Speed
  • 23WebHost – Hosting Miễn Phí 100GB

LIÊN KẾT

  • Có nên thuê thiết kế website giá rẻ?
  • Hướng dẫn thanh toán
  • Chính sách hoàn tiền
  • Trung tâm hỗ trợ

Copyright © 2023 | All rights reserved | HOANG WEB
Mọi hình thức sao chép nội dung trên website này mà chưa được sự đồng ý đều là trái phép.