Mình đã giới thiệu với các bạn về Quartz Scheduler để lên lịch để chạy một tác vụ nào đó, ở một thời điểm nào đó. Có một số vấn đề cần thiết cho các phần mềm ngày nay mà Quartz Scheduler không hỗ trợ như Dashboard UI để monitor các scheduler job hay đối với các distributed system bao gồm nhiều instance cho một application, làm thế nào để đảm bảo chỉ một scheduler job của ứng dụng được chạy thay vì mỗi instance của ứng dụng sẽ tự động trigger job để chạy riêng biệt? … Có nhiều alternative thư viện khác thay thế Quartz Scheduler để giải quyết các vấn đề này, một trong số đó, phổ biến nhất là thư viện JobRunr. Trong bài viết này, mình sẽ giới thiệu với các bạn cơ bản về JobRunr và hãy xem Dashboard UI của nó như thế nào các bạn nhé!
Đầu tiên, mình sẽ tạo mới một Maven project để làm ví dụ:
JobRunr dependency được khai báo như sau:
1 2 3 4 5 |
<dependency> <groupId>org.jobrunr</groupId> <artifactId>jobrunr</artifactId> <version>7.5.3</version> </dependency> |
Ngoài ra, các bạn cần khai báo thêm một trong 3 dependencies sau:
1 2 3 4 5 |
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.19.1</version> </dependency> |
hoặc:
1 2 3 4 5 |
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.13.1</version> </dependency> |
hoặc:
1 2 3 4 5 |
<dependency> <groupId>org.eclipse</groupId> <artifactId>yasson</artifactId> <version>3.0.4</version> </dependency> |
để JobRunr có thể sử dụng cho việc serialize và deserialize Java object qua JSON. JobRunr sẽ serialize thông tin job để lưu vào memory hoặc database và sẽ deserialize khi lấy chúng ra.
Đầu tiên, mình sẽ tạo một class main để chạy ứng dụng:
1 2 3 4 5 6 7 8 |
package com.huongdanjava.jobrunr; public class Application { public static void main(String[] args) { } } |
Để tạo một scheduler job với JobRunr, chúng ta sẽ sử dụng đối tượng của class JobScheduler. Các bạn có thể khởi tạo đối tượng JobScheduler này sử dụng class JobRunr, ví dụ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.huongdanjava.jobrunr; import org.jobrunr.configuration.JobRunr; import org.jobrunr.scheduling.JobScheduler; import org.jobrunr.storage.InMemoryStorageProvider; public class Application { public static void main(String[] args) { JobScheduler jobScheduler = JobRunr.configure() .useStorageProvider(new InMemoryStorageProvider()) .useBackgroundJobServer() .useDashboard() .initialize() .getJobScheduler(); } } |
Như các bạn thấy, mình đã sử dụng class JobRunr để cấu hình cho JobScheduler trước khi khởi tạo nó.
JobRunr lưu trữ thông tin chi tiết của job sử dụng một implementation nào đó của interface StorageProvider. Thông tin job detail này có thể lưu trữ sử dụng memory, các SQL database hay NoSQL database cơ bản như MariaDB, MySQL, PostgreSQL, MongoDB, … Các bạn có thể xem danh sách implementation của interface StorageProvider như sau:
Ở đây, để đơn giản, mình chỉ sử dụng memory với implementation là InMemoryStorageProvider!
Phương thức useBackgroundJobServer() sẽ khởi tạo đối tượng BackgroundJobServer để thực thi tác vụ. Ở ví dụ này, mình sử dụng các cấu hình mặc định cho đối tượng BackgroundJobServer các bạn nhé!
Phương thức useDashboard() dùng để enable Dashboard UI đó các bạn.
Sau khi đã có đối tượng SchedulerJob, các bạn có thể sử dụng phương thức enqueue() với tham số là Functional Interface JobLamdba, của đối tượng này để thực thi một tác vụ. Ví dụ của mình như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.huongdanjava.jobrunr; import org.jobrunr.configuration.JobRunr; import org.jobrunr.scheduling.JobScheduler; import org.jobrunr.storage.InMemoryStorageProvider; public class Application { public static void main(String[] args) { JobScheduler jobScheduler = JobRunr.configure() .useStorageProvider(new InMemoryStorageProvider()) .useBackgroundJobServer() .useDashboard() .initialize() .getJobScheduler(); jobScheduler.enqueue(() -> System.out.println("Hello from Huong Dan Java")); } } |
Kết quả:
Nếu các bạn muốn schedule một tác vụ, các bạn có thể sử dụng phương thức schedule() của đối tượng JobScheduler, ví dụ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package com.huongdanjava.jobrunr; import java.time.Instant; import java.time.temporal.ChronoUnit; import org.jobrunr.configuration.JobRunr; import org.jobrunr.scheduling.JobScheduler; import org.jobrunr.storage.InMemoryStorageProvider; public class Application { public static void main(String[] args) { JobScheduler jobScheduler = JobRunr.configure() .useStorageProvider(new InMemoryStorageProvider()) .useBackgroundJobServer() .useDashboard() .initialize() .getJobScheduler(); jobScheduler.schedule(Instant.now().plus(1, ChronoUnit.MINUTES), () -> System.out.println("Hello from Huong Dan Java")); } } |
Chạy ví dụ này, các bạn sẽ thấy 1 phút sau khi chúng ta chạy, dòng chữ “Hello from Huong Dan Java” sẽ được in ra.
Để access vào Dashboard UI của JobRunr, các bạn có thể đi đến địa chỉ http://localhost:8000/, kết quả của mình như sau:
Cho ví dụ của mình, nếu mới chạy ví dụ, các bạn sẽ thấy thông tin của job trong menu Jobs -> Scheduled như sau:
“38 seconds from now” có nghĩa tác vụ của mình sẽ được thực thi trong vòng 38 giây nữa đó các bạn!
Thông tin job sẽ chuyển từ các trạng thái Scheduled qua Enqueued qua Processing và cuối cùng là Succeeded hoặc Failed hoặc Deleted. Các bạn có thể dễ dàng theo dõi trong phần UI này.