Nội dung
- shares
- 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 tasksfunction 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ọiparent::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 Messenger
- Gmail
- Viber
- Skype
Best cook books says
Xin chào ngài !! Cảm ơn đã chia sẻ !! Người yêu thích của bạn Bạn !!
shrey jack says
Plugin nào được sử dụng để giảm thời gian tải blog của tôi
technical dadaji says
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?