Scheduler bawaan Spring menyediakan cara praktis untuk menjalankan tugas berjadwal di Java, tetapi memiliki keterbatasan dalam lingkungan enterprise. Dengan mengintegrasikan pekerjaan Spring Anda ke SchedulerX, Anda dapat meningkatkan fungsionalitasnya melalui fitur tingkat enterprise seperti pemantauan, penjadwalan lanjutan, dan ketersediaan tinggi.
Prasyarat
-
Agen SchedulerX versi 1.8.13 atau yang lebih baru telah terinstal.
-
Aplikasi Spring Boot Anda telah terhubung ke SchedulerX. Untuk informasi selengkapnya, lihat Hubungkan aplikasi Spring Boot ke SchedulerX.
Prosedur
Langkah 1: Tambahkan dependensi
Pada aplikasi Spring Boot, tambahkan dependensi SchedulerX ke file pom.xml Anda.
Gunakan versi agen terbaru untuk schedulerx2.version. Untuk informasi selengkapnya, lihat Catatan Rilis Agen.
<dependency>
<groupId>com.aliyun.schedulerx</groupId>
<artifactId>schedulerx2-spring-boot-starter</artifactId>
<version>${schedulerx2.version}</version>
<!-- Jika Anda menggunakan Logback, Anda harus mengecualikan Log4j dan Log4j2. -->
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
Baik Anda baru memulai dengan pekerjaan Spring maupun sudah memiliki pekerjaan yang ada, Anda harus tetap menyertakan anotasi @EnableScheduling di kelas utama Anda untuk mengaktifkan penjadwalan.
@SpringBootApplication
@EnableScheduling /** Aktifkan pekerjaan berjadwal Spring. */
public class SchedulerXWorkerApplication {
public static void main(String[] args) {
SpringApplication.run(SchedulerXWorkerApplication.class, args);
}
}
/** Kelas pekerjaan berjadwal Spring asli. */
@Service
public class SpringScheduledProcessor {
@Scheduled(cron = "0/2 * * * * ?")
public void hello() {
logger.info(DateUtil.now() + " hello world. start");
logger.info(DateUtil.now() + " hello world. end");
}
}
Secara default, setelah Anda menambahkan dependensi tersebut, SchedulerX tidak mengelola pekerjaan Spring yang sudah ada. Pekerjaan tersebut tetap dijadwalkan oleh kontainer Spring, dan eksekusinya tidak terpengaruh.
Langkah 2: Tambahkan parameter konfigurasi
Agar SchedulerX dapat mengelola pekerjaan Spring Anda, tambahkan konfigurasi berikut ke file application.properties Anda.
# 1. Konfigurasi akses aplikasi
spring.schedulerx2.endpoint=${endpoint}
spring.schedulerx2.namespace=${namespace}
spring.schedulerx2.groupId=${groupId}
spring.schedulerx2.appKey=${appKey}
# 2. Aktifkan SchedulerX untuk mengelola pekerjaan Spring
spring.schedulerx2.task.scheduling.scheduler=schedulerx
# 3. Opsional: Aktifkan sinkronisasi otomatis untuk pekerjaan Spring yang sudah ada
#spring.schedulerx2.task.scheduling.sync=true
#spring.schedulerx2.regionId=Tentukan ID wilayah untuk sinkronisasi pekerjaan.
#spring.schedulerx2.aliyunAccessKey=XXXXXXXXX
#spring.schedulerx2.aliyunSecretKey=XXXXXXXXX
Penjelasan parameter:
-
Konfigurasi akses aplikasi: Masuk ke Konsol SchedulerX. Di panel navigasi sebelah kiri, klik Application Management. Temukan aplikasi Anda, lalu di kolom Actions, klik Access Configuration untuk mendapatkan kredensial Anda. Jika ini pertama kalinya Anda menghubungkan, Anda harus membuat kelompok aplikasi.
-
Konfigurasi sinkronisasi otomatis: Jika Anda memiliki banyak pekerjaan Spring yang sudah ada, Anda dapat mengaktifkan sinkronisasi otomatis untuk menghindari pembuatan tugas secara manual seperti yang dijelaskan di Langkah 3. Untuk daftar ID wilayah, lihat Endpoints.
Untuk menjaga konsistensi dengan aturan menjalankan pekerjaan Spring asli di lingkungan kluster, pekerjaan yang disinkronkan secara otomatis ke platform SchedulerX menggunakan mode eksekusi broadcast run secara default. Artinya, setiap mesin dalam kluster menjalankan pekerjaan tersebut pada waktu yang dijadwalkan. Jika bisnis Anda mengharuskan hanya satu mesin dalam kluster yang menjalankan pekerjaan tersebut, Anda dapat mengubah mode eksekusi pekerjaan menjadi stand-alone operation di konsol. Untuk informasi selengkapnya tentang parameter tersebut, lihat Langkah 3.
Langkah 3 (Opsional): Buat tugas secara manual
Jika Anda telah mengaktifkan sinkronisasi otomatis di Langkah 2, Anda dapat melewati langkah ini.
-
Masuk ke Konsol SchedulerX.
-
Di panel navigasi sebelah kiri, klik task management.
-
Pada halaman task management, klik Create Task. Pilih SpringSchedule sebagai jenis tugas dan konfigurasikan nama kelas serta metode.
Parameter
Deskripsi
Name
Nama unik untuk mengidentifikasi tugas.
Description
Deskripsi opsional untuk membantu Anda mencari dan mengelola tugas.
Application ID
Kelompok aplikasi tempat tugas tersebut berada. Pilih opsi dari daftar drop-down.
Job Type
Jenis prosesor untuk tugas tersebut. Nilai yang valid: Java, Shell, Python, Go, HTTP, Node.js, SpringSchedule, XXL-JOB, dan DataWorks. Jika Anda memilih Shell, Python, atau Go, editor skrip akan muncul.
Untuk tutorial ini, pilih SpringSchedule.
Spring Schedule Configuration
Nama kelas lengkap dan nama metode dari tugas tersebut.
Execution Mode
Menentukan cara tugas dieksekusi di beberapa instans. Mode berikut didukung:
-
Stand-alone operation: Menjalankan tugas pada satu instans yang dipilih secara acak.
-
Broadcast run: Menjalankan tugas pada semua instans secara bersamaan.
CatatanPengaturan lanjutan berubah sesuai dengan mode eksekusi yang dipilih.
Priority
Jika beberapa tugas dalam aplikasi yang sama siap dijalankan pada instans yang sama, tugas dengan prioritas lebih tinggi akan dijalankan terlebih dahulu. SchedulerX menggunakan antrian prioritas preemptible untuk memastikan tugas berprioritas tinggi dieksekusi terlebih dahulu, bahkan di berbagai instans. Untuk informasi selengkapnya, lihat Throttling Tingkat Aplikasi dengan Antrian Prioritas.
Job Parameters
String kustom yang dapat diambil dari konteks pekerjaan saat runtime.
-
-
Konfigurasikan jadwal.
CatatanJadwal yang dikonfigurasi di konsol menggantikan jadwal yang ditentukan dalam anotasi
@Scheduleddi kode Anda. Namun, Anda harus tetap menyimpan anotasi tersebut di kode Anda.Tabel berikut menjelaskan parameter berbasis waktu.
Parameter
Deskripsi
Time Type
-
none: Tugas tidak dijadwalkan dan biasanya dipicu oleh alur kerja.
-
cron: Tugas dijadwalkan menggunakan ekspresi cron.
-
api: Tugas dipicu oleh panggilan API.
-
fixed_rate: Tugas dipicu dengan frekuensi tetap.
-
second_delay: Tugas dipicu setelah penundaan tetap dalam hitungan detik.
-
one_time: Tugas hanya dijalankan sekali.
Cron Expression (hanya untuk tipe waktu cron)
Masukkan ekspresi cron standar. Anda juga dapat menggunakan tool bawaan untuk menghasilkan dan memvalidasi ekspresi tersebut.
Fixed frequency (hanya untuk tipe waktu fixed_rate)
Masukkan interval dalam detik. Nilainya harus lebih besar dari atau sama dengan 60. Misalnya, nilai 200 berarti tugas dijalankan setiap 200 detik.
Fixed delay (hanya untuk tipe waktu second_delay)
Masukkan penundaan dalam detik. Nilainya harus antara 1 hingga 60. Misalnya, nilai 5 berarti tugas dipicu 5 detik setelah waktu yang dijadwalkan.
Tabel berikut menjelaskan parameter konfigurasi lanjutan.
Parameter
Deskripsi
Data Timestamp Offset
Offset antara waktu data dan waktu jadwal. Anda dapat mengambil nilai ini dari konteks pekerjaan saat runtime.
Time Zone
Pilih zona waktu sesuai kebutuhan bisnis Anda. Zona waktu regional maupun GMT standar didukung.
Calendar
Anda dapat memilih kalender, seperti kalender hari kerja atau hari keuangan, untuk membatasi eksekusi tugas hanya pada hari-hari tertentu.
-
-
Atur aturan peringatan dan saluran notifikasi. Untuk informasi selengkapnya, lihat Kelola Kontak Notifikasi.
Setelah menyelesaikan langkah-langkah ini, SchedulerX akan mengelola pekerjaan Spring Anda dan menyediakan kemampuan tingkat enterprise, seperti pemantauan visual, kueri log, pelacakan eksekusi, dan peringatan.
Langkah 4: Verifikasi integrasi
-
Jalankan aplikasi Spring Anda. Setelah aplikasi berjalan, masuk ke Konsol SchedulerX dan klik Application Management di panel navigasi sebelah kiri. Verifikasi bahwa instans aplikasi Anda muncul dalam daftar.
Di kolom Instances, pastikan jumlahnya lebih dari 0. Anda juga dapat mengklik View Instances di kolom Actions untuk melihat detail instans yang terhubung.
-
Di panel navigasi sebelah kiri, klik task management. Temukan tugas untuk aplikasi Anda dan klik Run Once di kolom Actions. Eksekusi yang berhasil mengonfirmasi integrasi tersebut.
FAQ
Mengapa pengatur waktu Spring asli tetap berjalan setelah SchedulerX mengambil alih?
Jika scheduler kustom ditentukan dalam aplikasi Anda, SchedulerX akan menimpa scheduler kustom tersebut. Konflik ini biasanya terjadi ketika suatu kelas mengimplementasikan org.springframework.scheduling.annotation.SchedulingConfigurer dan memanggil metode setScheduler dari ScheduledTaskRegistrar, yang menimpa scheduler default.
Untuk mengatasi masalah ini:
Cari di proyek Anda kelas apa pun yang mengimplementasikan
SchedulingConfigurer.Periksa apakah metode
setSchedulerdariScheduledTaskRegistrardipanggil.Jika salah satu kondisi tersebut benar, beri komentar pada kode scheduler kustom tersebut.
Bagaimana cara mendapatkan konteks pekerjaan dalam pekerjaan Spring?
Panggil ContainerFactory.getContainerPool().getContext() untuk mendapatkan JobContext saat ini:
// Dapatkan konteks pekerjaan SchedulerX di dalam metode @Scheduled
JobContext jobContext = ContainerFactory.getContainerPool().getContext();Dapatkah pekerjaan Spring mengembalikan hasil pemrosesan?
Fitur ini memerlukan agen SchedulerX versi lebih baru dari 1.10.11. Versi 1.10.11 dan sebelumnya tidak mendukung nilai kembali dari pekerjaan Spring.
Hasil pemrosesan dikembalikan berdasarkan metode penjadwalan yang ditentukan. Pekerjaan Spring mendukung dua tipe nilai kembali:
| Tipe nilai kembali | Kasus penggunaan |
|---|---|
ProcessResult | Mengembalikan status sukses/gagal beserta pesan hasil |
String | Mengembalikan hanya pesan hasil |
Kedua contoh berikut menggunakan anotasi @Scheduled dengan ekspresi cron.
Mengembalikan ProcessResult
Gunakan ProcessResult untuk menunjukkan status sukses atau gagal beserta pesan hasil:
@Scheduled(cron = "0/5 * * * * ?")
public ProcessResult helloStandalone1() {
try {
logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. start");
TimeUnit.SECONDS.sleep(2L);
logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. end");
} catch (Exception e) {
e.printStackTrace();
logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. exception end..");
}
// Argumen pertama: true untuk sukses, false untuk gagal
// Argumen kedua: pesan hasil
return new ProcessResult(true, "Processing result");
}Mengembalikan String
Kembalikan String secara langsung jika Anda tidak memerlukan indikator eksplisit sukses/gagal:
@Scheduled(cron = "0/5 * * * * ?")
public String helloStandalone2() {
try {
logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. start");
TimeUnit.SECONDS.sleep(2L);
logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. end");
} catch (Exception e) {
e.printStackTrace();
logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. exception end..");
}
return "Processing result";
}