Hướng dẫn php artisan schedule:run
Mặc định Laravel cung cấp các method schedule cho khai báo Cronjob: Show
Trong Laravel thời gian tối thiểu giữa 2 lần chạy job là 1 phút. Vì 1 lý do nào đó cần phải chạy 1 job định kỳ 20-30s chẳng hạn. Khi đó ta cần khai báo 1 job chạy định kỳ 1 phút và chia nhỏ phần thực thi. Sửa lại file Kernel.php protected function schedule(Schedule $schedule){ $schedule->call(function () use ($schedule) { $seconds = 10; $dt = Carbon::now(); $x= 60/$seconds; do{ echo $dt."\n"; Artisan::call('pokez'); Artisan::call('board'); time_sleep_until($dt->addSeconds($seconds)->timestamp); } while($x-- > 0); })->everyMinute(); } Ở đây mình chạy 2 job pokez và board, để kiểm tra user, định kỳ 10s 1 lần. Kiểm tra cho đúng, chạy lệnh `php artisan schedule:run` để xem kết quả. Nếu như này thì đã cấu hình đúng: [email protected] pokez.laravel.vip % php artisan schedule:run Running scheduled command: Closure 2019-12-12 02:10:09 2019-12-12 02:10:19 2019-12-12 02:10:29 2019-12-12 02:10:39 Trong các công việc cần thực hiện trên một hệ thống website, đôi khi một số công việc chúng ta cần thực hiện theo một kế hoạch định trước, ví dụ như chúng ta cần xóa các dữ liệu tạm trong các bảng của cơ sở dữ liệu vào giữa đêm hoặc chúng ta muốn tổng hợp các báo cáo tốn rất nhiều tài nguyên vào cuối ngày để hôm sau có thể truy cập được ngay... Laravel Task Scheduling cho phép bạn thực hiện các công việc theo một kế hoạch đặt trước. 1. Thiết lập thời gian biểuLaravel Task Scheduling cho phép bạn lập thời gian biểu để chạy thực hiện các loại ứng dụng sau: 1. Một lời gọi đến Closure
3. Một câu lệnh trong hệ điều hành
Các công việc cần thực hiện và thời gian biểu cần được định nghĩa trong phương thức schedule() của lớp App\Console\Kernel (file app\Console\Kernel.php). Trong ví dụ tiếp theo, chúng ta sẽ thực thi một câu lệnh artisan inspire cứ 5 phút một lần vào xuất nội dung vào một file inspire.txt nằm trong ổ C. Trước tiên chúng ta cần định nghĩa trong app\Console\Kernel.php.
Câu lệnh artisan inspire là câu lệnh hiển thị ngẫu nhiên một câu danh ngôn, Taylor Otwell khá dị nhân khi có những câu lệnh kiểu này :). Bạn mở command line với thư mục hiện hành là thư mục gốc của dự án và thử câu lệnh php artisan inspire: 2. Đặt lịch thực hiện trong hệ điều hànhBản thân laravel không tự thực hiện được các task schedule này mà nó thông qua các công cụ đặt lịch chạy ngầm của hệ điều hành (HĐH). Với Windows chúng ta có Windows Task Scheduler, với Linux chúng ta có CRON, với MacOS có automator. Tiếp theo chúng ta sẽ đi vào đặt lịch thực hiện cho từng HĐH riêng. 2.1 Đặt lịch trong WindowsTrong hệ điều hành Windows có công cụ Windows Task Scheduler chuyên để đặt lịch thực thi các ứng dụng trong hệ thống. Bạn có thể mở công cụ này với các bước như sau: Cách 1: Trong Ô Search programs and files (phím tắt phím Windows + R), nhập Taskschd.msc và gõ Enter. Cách 2: Chuột phải vào My Computer chọn Manage, trong tab bên tay trái bạn sẽ thấy Task Scheduler. Sau khi mở được công cụ Windows Task Scheduler chúng ta tiếp tục các bước để đặt lịch thực hiện. Bước 1: Tạo một lịch thực hiện, bấm vào Create Task... Bước 2: Các thiết lập căn bản trong Task Scheduler như tên, chế độ chạy, user chạy... Bước 3: Thiết lập Trigger, chúng ta muốn Task Scheduler thực thi theo thời gian như thế nào, ví dụ ở đây chúng ta thiết lập chạy hàng ngày với lịch chạy con là 1 lần/1 phút. Chú ý, thời gian thực hiện trong Windows Task Scheduler phải dày đặc hơn thời gian thiết lập trong phương thức schedule(). Bước 4: Thiết lập Action chính là cái gì chúng ta cần thực hiện Chúng ta đang cần thực hiện câu lệnh php artisan inspire một cách định kỳ, thực chất là chúng ta thực hiện câu lệnh php artisan schedule:run, bạn có thể chạy thử câu lệnh này tại thư mục gốc của dự án và kiểm tra file C:/inspire.txt. Trong đây có một số chú ý:
OK, như vậy bạn đã đặt xong lịch chạy php artisan schedule:run trên môi trường Windows. Bạn kiểm tra và cứ 5 phút một câu danh ngôn sẽ được đưa vào file C:/inspire.txt. 2.2 Đặt lịch trong Unix, LinuxCron là một công cụ đặt lịch thực hiện theo thời gian trong các hệ điều hành như Unix, Linux, các công việc, nhiệm vụ (job, task) được gọi là cron job. Cron là một ứng dụng daemon, là một ứng dụng chạy ngầm và được khởi tạo cùng hệ thống. Thời gian biểu chạy các ứng dụng sẽ được đưa vào một file cấu hình và file này được gọi là crontab. Chúng ta cùng xem xét một cron job như sau:
Một cron job sẽ có hai phần chính:
2.2.1 Cú pháp thời gian biểu trong cron jobMỗi một dấu * trong phần thời gian biểu cron job thể hiện thời gian lặp lại trong phút, giờ, ngày trong tháng, tháng và ngày trong tuần, nó có thể là một giá trị số cụ thể. Chúng ta cùng xem một số ví dụ sau: ` * [command] lịch này sẽ thực hiện mỗi phút một lần. 15 [command] lịch này thực hiện mỗi giờ một lần và vào phút thứ 15. 15 2 1 [command] thực hiện vào mỗi thứ hai hàng tuần vào lúc 2:15 am. 2.2.2 Câu lệnh thực hiệnCâu lệnh thực hiện bao gồm 3 phần:
3. Một số các tùy chọn trong thiết lập task schedule trong Laravel3.1 Các tùy chọn tần suất trong lịch thực hiệnMột chú ý là tại sao trong phần đặt lịch của Hệ điều hành chúng ta đã thực hiện đặt lịch nhưng trong Task Scheduling của Laravel chúng ta lại đặt lịch tiếp? Cái nào ưu việt hơn? Nếu bạn muốn đặt lịch trong Laravel thì lịch của hệ điều hành nên để là thực hiện mỗi phút một lần (trong cron job để là *) và lịch chi tiết sẽ thực hiện trong Laravel. Mỗi cách đặt lịch có một số ưu điểm:
Do vậy, tùy từng loại công việc, nhiệm vụ cần thực hiện bạn nên lựa chọn đặt lịch chính xác bằng HĐH hay thông qua Laravel. Laravel hỗ trợ tùy chọn tần suất thực hiện cũng giống như trong HĐH như trong danh sách sau:
Chúng ta cùng xem một số ví dụ sau:
Ví dụ trên sẽ thực hiện câu lệnh ipconfig (câu lệnh xem các thông tin về địa chỉ IP trên máy) từ 8:00 đến 17:00 hàng giờ vào các ngày cuối tuần với múi giờ là giờ Việt Nam. 3.2 Thiết lập điều kiện thực hiện lịchCũng như trong đặt lịch sử dụng lịch hệ điều hành, Laravel cho phép thiết lập các điều kiện thực hiện lịch chi tiết hơn rất nhiều do có thể lập trình được. Laravel hỗ trợ một số phương thức ràng buộc điều kiện như sau:
Laravel cho phép bạn thực hiện các điều kiện phức tạp trong thực hiện lịch công việc với việc sử dụng phương thức when và skip bằng cách truyền vào một Closure. Với phương thức when() nếu Closure trả về true thì lịch sẽ được thực hiện, phương thức skip() thì ngược lại, nếu Closure trả về true thì lịch sẽ được bỏ qua. Ví dụ:
Ví dụ trên sẽ xóa bảng tạm chứa thông tin người dùng hàng ngày nếu tại thời điểm đó không có người dùng nào đang trong hệ thống. 3.3 Ngăn chặn thực hiện công việc chồng chéoKhi thực hiện các công việc bằng lịch tự động, rất có thể một công việc trước đó chưa hoàn thành, ví dụ bạn thực hiện tự động tổng hợp số liệu 5 phút một lần, tuy nhiên lần tổng hợp trước đó do dữ liệu quá lớn vẫn chưa có kết quả, như vậy bạn không muốn thực hiện tiếp lần tổng hợp tiếp theo sau 5 phút. Với việc sử dụng phương thức withoutOverlapping, Laravel sẽ bỏ qua lịch thực hiện nếu công việc trước đó chưa hoàn thành.
Tại sao Laravel có thể làm được việc này, nó sử dụng mutex là một khái niệm trong lập trình để giải quyết vấn đề liên quan đến xử lý đa luồng. Mutex sử dụng một cờ chung, nó hoạt động giống như người gác cổng, cho phép một luồng có thể truy nhập trong khi những luồng khác bị chặn. Nó đảm bảo rằng các mã được kiểm soát sẽ chỉ được chạy bởi một luồng đơn tại một thời điểm. Laravel tạo ra một mutex khi bắt đầu thực hiện một công việc và mỗi lần thực thi nó sẽ kiểm tra nếu mutex tồn tại, công việc đó sẽ không được thực hiện. Bạn có thể xem cách mutex hoạt động trong phương thức withoutOverlapping trong class Illuminate/Console/Scheduling/Event.php:
Laravel tạo ra một phương thức callback để lọc và thông báo với Schedule Manager bỏ qua công việc nếu một mutex vẫn đang tồn tại, nó cũng tạo ra một callback để xóa mutex sau khi công việc hoàn thành. Trước khi thực hiện công việc, Laravel thực hiện kiểm tra trong phương thức run của Illuminate/Console/Scheduling/Event:
Trong khi một đối tượng được tạo từ Illuminate\Console\Scheduling\Schedule, trong phương thức khởi tạo của Schedule, Laravel sẽ kiểm tra nếu một thực thi của interface Illuminate\Console\Scheduling\Mutex được gắn vào container không, nếu có nó sẽ sử dụng đối tượng này, nếu không nó sử dụng một đối tượng từ class Illuminate\Console\Scheduling\CacheMutex:
Khi đó Schedule Manager sẽ đăng ký các sự kiện này và truyền vào một instance của mutex:
Laravel mặc định sử dụng mutex có sử dụng bộ đệm, bạn có thể sử dụng phương pháp khác. Class CacheMutex chứa 3 phương thức đơn giản sử dụng các event name như là key:
Như ở trên đã nói, Schedule Manager có một callback để xóa mutex liên quan sau khi công việc hoàn thành, với một công việc chạy một lệnh của hệ điều hành, có thể không đảm bảo rằng mutex được xóa nhưng với callback, script có thể dừng trong khi thực thi callback để ngăn chặn một fallback được thêm vào Illuminate\Console\Scheduling\CallbackEvent::run()
3.4 Chế độ bảo trì hệ thốngNếu bạn chuyển hệ thống sang chế độ bảo trì trong Laravel, toàn bộ các lịch thực hiện tự động thông thường sẽ không hoạt động, nếu bạn muốn một lịch tự động thực hiện ngay cả khi hệ thống được chuyển sang chế độ bảo trì, bạn có thể sử dụng phương thức evenInMaintenanceMode() khi định nghĩa lịch thực hiện. 3.5 Xuất dữ liệu khi chạy lịch thực hiện công việcLaravel cung cấp rất nhiều phương thức hỗ trợ xuất dữ liệu đầu ra khi thực hiện các công việc: Phương thức sendOutputTo xuất dữ liệu ra một file trong một thư mục:
Nếu bạn muốn ghi tiếp một file, sử dụng phương thức appendOutputTo:
Bạn cũng có thể gửi email các dữ liệu đầu ra khi thực hiện một công việc theo lịch với phương thức emailOutputTo, trước khi định nghĩa lịch thực hiện này bạn cần thiết lập Laravel Mail:
3.6 Task HookHook là những phương thức được thực hiện trong một thời điểm nào đó của vòng đời một đối tượng, ở đây đối tượng chính là các công việc được thực hiện theo lịch. Laravel cho phép bạn có thể thực hiện một số các công việc trước hoặc sau khi một lịch thực hiện công việc được bắt đầu hoặc kết thúc thông qua các phương thức before(), after():
Ngoài ra Laravel có các phương thức pingBefore, thenPing để có thể thực hiện ping một URL một cách tự động trước hoặc sau khi một nhiệm vụ được hoàn thành. Phương thức này là cực kỳ hữu ích để thông báo cho một dịch vụ ở ngoài.
CÁC BÀI VIẾT KHÁC |