Dokumen ini menjelaskan cara melakukan troubleshooting terhadap masalah umum dalam pengelolaan pekerjaan di SchedulerX.
Troubleshooting bean Spring yang tidak ditemukan
Di halaman manajemen aplikasi, hubungkan ke worker dan pastikan mode startup-nya adalah Spring atau Spring Boot.
Inject
JobProcessorsebagaibean, misalnya dengan menambahkan anotasi@Component.Periksa dependensi pom Anda. Jika terdapat dependensi pada
spring-boot-devtools, Anda harus mengecualikannya.Jika JobProcessor atau metode process menggunakan anotasi AOP, lakukan upgrade agen SchedulerX ke versi terbaru karena versi sebelumnya tidak mendukung AOP.
Lapisan proxy tambahan dapat menyebabkan ketidaksesuaian tipe bean. Untuk mendiagnosis hal ini, letakkan breakpoint di kelas
DefaultListableBeanFactory. Variabel anggotabeanDefinitionNamesmencantumkan semua bean yang terdaftar di Spring. Periksa daftar ini untuk melihat apakah suatu bean diproksi oleh aspek, yang dapat terjadi jika pustaka pihak ketiga yang salah diimpor secara tidak langsung. Jika demikian, kecualikan pustaka tersebut.
Jika solusi di atas tidak menyelesaikan masalah, lakukan debug pada metode ThreadContainer.start. Jika terjadi error class.forName untuk kelas yang Anda ketahui ada, kemungkinan besar disebabkan oleh framework yang digunakan aplikasi Anda sehingga menyebabkan inkonsistensi classLoader. Anda dapat mengatasi hal ini dengan mengatur SchedulerxWorker.setClassLoader.
Pekerjaan gagal dengan pesan "Unable to make field private"
MapReduce menggunakan framework serialisasi dan deserialisasi. Mulai Java 9, akses reflektif ke variabel pribadi harus diaktifkan secara manual. Tambahkan parameter berikut ke argumen JVM Anda:
--add-opens java.base/java.lang=ALL-UNNAMEDPekerjaan gagal dengan pesan "submit jobInstanceId to worker timeout"
Anda dapat mengabaikan error ini jika hanya terjadi selama rilis aplikasi atau jarang terjadi.
Jika error ini terus-menerus terjadi pada workerAddr yang sama, hal tersebut menunjukkan koneksi persisten antara server dan agen terputus. Restart node pekerja atau lakukan upgrade agen SchedulerX. Setelah upgrade, agen dapat secara otomatis memulihkan koneksi yang terputus.
Pekerjaan gagal dengan pesan "used space beyond 90,0%!"
Disk penuh. Anda perlu membersihkan ruang disk pada Instance ECS atau kontainer.
Pekerjaan gagal dengan pesan "ClassNotFoundException"
Error ini menunjukkan bahwa kelas tersebut tidak ditemukan pada worker yang menjalankan pekerjaan. Pastikan Class full path yang dikonfigurasi untuk pekerjaan Java merupakan nama lengkap kelas (fully qualified name), bukan singkatan.
Sebagai contoh, path lengkap yang benar adalah com.aliyun.schedulerx.example.processor.DtsSimpleJob.
Jika Class full path yang dikonfigurasi sudah benar tetapi kelas tersebut tidak ada di worker, biasanya disebabkan oleh penerapan paket yang salah atau aplikasi terhubung ke worker milik pengguna lain. Anda dapat login ke worker tersebut dan menggunakan decompiler untuk menyelidiki.
Pekerjaan gagal dengan pesan "jobInstance=xxx don't update progress more than 60s"
Server akan memaksa menghentikan pekerjaan jika worker yang menjalankannya berhenti atau sedang dalam proses rilis dan gagal melaporkan progres selama lebih dari 60 detik. Jika Anda memastikan bahwa masalah disebabkan oleh worker atau worker tersebut sudah tidak ada, tidak diperlukan tindakan apa pun.
Pekerjaan gagal tanpa pesan error
Gejala:
Suatu pekerjaan gagal, tetapi tidak ada pesan error yang ditampilkan.
Kemungkinan penyebab:
Kegagalan pada worker atau kegagalan dalam logika bisnis.
Solusi:
Di halaman Instances, buka tab Task instance List. Temukan instans pekerjaan yang dimaksud, klik Actions di kolom Details untuk membuka panel Task instance details, lalu identifikasi worker tempat pekerjaan tersebut gagal.
Ini adalah alamat worker yang menjalankan pekerjaan tersebut.
Login ke worker tersebut dan buka file log ~/logs/schedulerx/worker.log.
Jalankan
grep <Instance ID> worker.loguntuk melihat log yang terkait dengan instans tersebut. Jika terdapat exception bertingkat ERROR, periksa stack trace untuk mengetahui penyebab spesifiknya.Jika deskripsi error kosong, kemungkinan besar masalah terletak pada logika bisnis Anda yang tidak mengembalikan pesan kegagalan. Anda perlu menyelidiki kode bisnis Anda untuk mengidentifikasi penyebabnya.
Jika deskripsi error berisi exception framework, bergabunglah dengan grup DingTalk (ID: 23103656) untuk menghubungi dukungan teknis SchedulerX.
Troubleshooting kegagalan pekerjaan
Untuk pekerjaan standalone yang melemparkan exception, buka halaman Instances, klik tab Task instance List, temukan instans pekerjaan yang dimaksud, lalu klik Actions di kolom Details untuk melihat pesan error.
Jika pekerjaan tidak melemparkan exception atau merupakan pekerjaan terdistribusi, Anda dapat menggunakan Log Service untuk melakukan troubleshooting pada aplikasi Edisi Profesional.
Untuk aplikasi Edisi Dasar, login ke node pekerja dan periksa log SchedulerX serta log bisnis.
Pekerjaan macet
Gejala:
Pekerjaan terjadwal macet dalam status running dan tidak pernah selesai.
Kemungkinan penyebab:
Masalah dalam logika bisnis Anda.
Masalah dalam SchedulerX.
Solusi: Anda dapat melakukan troubleshooting masalah logika bisnis dengan mengikuti langkah-langkah berikut. Untuk masalah lainnya, bergabunglah dengan grup DingTalk (ID: 23103656) untuk menghubungi dukungan teknis SchedulerX.
Untuk aplikasi Edisi Profesional: Gunakan ThreadDump di Konsol untuk mendapatkan stack trace exception pekerjaan. Fitur ini tersedia untuk versi agen 1.4.2 ke atas.
Untuk aplikasi Edisi Dasar: Login ke node pekerja yang macet dan gunakan perintah
jstackuntuk melihat stack trace. Jalankan perintah berikut:jstack <pid> | grep <job instance ID> -A 20$jstack 29191 |grep 58903617 -A 200 "Schedulerx-Container-Thread-58903617-0" #4093 prio=5 os_prio=0 tid=xxx nid=xxx waiting on condition [0x00002ad443101000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000072b837ae0> (a java.util.concurrent.CountDownLatch$Sync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304) at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231) at com.aliyun.ticket.importworker.WOImportJob.startImport(WOImportJob.java:353) at com.aliyun.ticket.importworker.WOImportJob.doImportForAll(WOImportJob.java:242) at com.aliyun.ticket.importworker.WOImportJob.process(WOImportJob.java:163) at com.alibaba.schedulerx.worker.container.ThreadContainer.start(ThreadContainer.java:90) at com.alibaba.schedulerx.worker.container.ThreadContainer.run(ThreadContainer.java:60) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:756) "Container-Batch-Statues-Retrieve-Thread-58903617" #4092 prio=5 os_prio=0 tid=xxx nid=xxx waiting on condition [0x00002ad44fe0e000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at com.alibaba.schedulerx.worker.batch.BaseReqHandler$2.run(BaseReqHandler.java:74) at java.lang.Thread.run(Thread.java:756) "TDDL-Druid-ConnectionPool-DestroyScheduler--2-thread-237" #4052 daemon prio=5 os_prio=0 tid=xxx nid=xxx waiting on condition [0x00002ad462e00] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007436c7190> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:1129) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
Troubleshooting pekerjaan lambat
Aktifkan Analisis Tracing pada Edisi Profesional. Untuk informasi lebih lanjut, lihat Integrasikan Analisis Tracing.
Batas instans pekerjaan tercapai
Gejala:
Di halaman Job Management, saat mengklik Run once, muncul prompt:
The number of running job instances has reached the upper limit. Please try again later.Kemungkinan penyebab:
Instans pekerjaan ini sedang berjalan.
Jumlah instans pekerjaan yang sedang berjalan telah mencapai batas konkurensi maksimum yang dikonfigurasi untuk pekerjaan tersebut.
Solusi:
Jika pengaturan konkurensi sudah sesuai, tidak diperlukan tindakan apa pun. Di halaman Job Management, Anda dapat melihat instans pekerjaan yang sedang berjalan dengan mengklik .
Jika batas konkurensi ini terlalu ketat, klik Actions di kolom Edit untuk pekerjaan tersebut dan tingkatkan Instance concurrency pada pengaturan lanjutan.
Pekerjaan belum selesai: Diantrikan atau dilewati?
Secara default, konkurensi instans adalah 1, artinya pekerjaan dijalankan secara serial. Jika pekerjaan berdurasi panjang belum selesai pada waktu penjadwalan berikutnya, eksekusi baru akan dibuang, bukan diantrikan.
Jika konkurensi instans diatur ke 2, dan eksekusi sebelumnya belum selesai, instans lain tetap dapat dimulai pada waktu penjadwalan berikutnya. Maksimal dua instans pekerjaan dapat berjalan secara bersamaan.
Buat pekerjaan satu kali
Untuk membuat pekerjaan satu kali, pilih one_time sebagai tipe waktu. SchedulerX 2.0 mendukung fitur ini, tetapi pekerjaan tersebut tidak menyimpan catatan eksekusi.
Lihat riwayat pekerjaan satu kali
Pekerjaan one_time secara otomatis dihapus setelah dijalankan untuk mencegah akumulasi data, dan tidak ada riwayat yang disimpan. Jika Anda perlu menyimpan catatan eksekusi, Anda dapat mengaktifkan Log Service, yang menyimpan log eksekusi semua pekerjaan selama dua minggu terakhir untuk memudahkan troubleshooting. Untuk informasi lebih lanjut tentang cara mengaktifkan Log Service, lihat Manajemen Aplikasi.
Konfigurasi penjadwalan tingkat kedua
SchedulerX mendukung penjadwalan tingkat detik. Tipe waktu cron dan fix_rate tidak mendukung penjadwalan tingkat detik. Anda dapat memilih tipe waktu second_delay, yang menjalankan pekerjaan beberapa detik setelah eksekusi sebelumnya selesai.
Pekerjaan tidak dijadwalkan
Jika pekerjaan standalone tidak dijadwalkan pada waktu tertentu, periksa apakah ada worker dalam daftar worker dan pastikan tidak semua worker sedang sibuk. Jika tidak ada worker yang tersedia, lakukan troubleshooting berdasarkan status "no workers available" atau "all workers are busy". Untuk informasi lebih lanjut, lihat Apa yang harus dilakukan jika tidak ada worker yang tersedia? dan Apa yang harus dilakukan jika semua worker sedang sibuk?.
Kami merekomendasikan untuk mengonfigurasi alarm ketika tidak ada worker yang tersedia untuk suatu pekerjaan. Untuk informasi lebih lanjut, lihat Manajemen Pekerjaan.
Atur timeout di SchedulerX
SchedulerX mendukung timeout untuk keseluruhan pekerjaan, tetapi tidak untuk tugas individual. Anda dapat memodifikasi timeout secara dinamis di Konsol. Untuk informasi lebih lanjut, lihat Manajemen Pekerjaan.
Instans tetap berjalan setelah dihentikan
Gejala: Instans tetap berjalan setelah dihentikan.
Kemungkinan penyebab: Saat instans pekerjaan dihentikan, SchedulerX mengirim pesan kill ke agen. Agen kemudian berhenti mendispatch tugas baru dan menghancurkan konteks instans beserta kolam thread-nya. Namun, tugas yang sedang berjalan tidak dihentikan secara paksa. Thread-nya hanya diinterupsi, sehingga tetap dapat berjalan hingga selesai.
Solusi:
Pada sebagian besar kasus, tidak diperlukan tindakan apa pun. Tunggu hingga tugas selesai.
Jika Anda perlu segera menghentikan semua tugas yang sedang berjalan saat instans dihentikan, Anda harus memodifikasi logika pemrosesan tugas Anda agar menangani status interupsi thread saat ini.
Konfigurasi pengaturan pekerjaan lanjutan
Untuk informasi lebih lanjut, lihat Parameter lanjutan untuk manajemen pekerjaan.
Semua worker sedang sibuk
Di halaman manajemen aplikasi, lihat instans untuk menemukan worker yang sibuk. Lalu, klik Busy untuk melihat metrik mana yang telah melebihi ambang batas.
Ambang batas sibuk dikonfigurasi di halaman Application Management dengan mengklik Edit Application Group.
Di bagian Instance Busy Configuration pada langkah Basic Configurations, Anda dapat mengatur ambang batas untuk load5 (default: 0), Memory Usage (default: 90%), dan Disk Usage (default: 95%). Anda juga dapat menggunakan sakelar Enable Busy Worker Check untuk mengontrol apakah pemeriksaan sibuk diaktifkan.
Jika worker sibuk karena beban tinggi, periksa apakah aplikasi Anda diterapkan dalam kontainer (Kubernetes). Jika ya, Anda perlu mengonfigurasi dua parameter berikut. Jika tidak, penggunaan CPU yang dikumpulkan mungkin tidak akurat. Untuk informasi lebih lanjut, lihat Hubungkan aplikasi Spring Boot ke SchedulerX.
Parameter | Deskripsi | Nilai | Versi awal |
spring.schedulerx2.enableCgroupMetrics | Menentukan apakah akan menggunakan cgroup untuk mengumpulkan metrik instans agen. Anda harus mengaktifkannya secara manual di lingkungan kontainer (Kubernetes). | true/false. Default: false. | 1.2.2.2 |
spring.schedulerx2.cgroupPathPrefix | Path cgroup di dalam kontainer. | Default: /sys/fs/cgroup/cpu/. Anda tidak perlu mengatur parameter ini jika path ini ada. | 1.2.2.2 |
Integrasikan Analisis Tracing
Penjadwalan pekerjaan mendukung analisis tracing end-to-end. Untuk informasi lebih lanjut, lihat Integrasikan Analisis Tracing.
Pekerjaan macet atau lambat selama rilis aplikasi
Gejala: Eksekusi pekerjaan macet atau lambat selama rilis aplikasi.
Kemungkinan penyebab: Untuk pekerjaan terdistribusi, jika worker yang sedang memproses tugas offline, tugas-tugas tersebut didistribusikan ulang, dan sistem melakukan polling untuk memeriksa apakah worker tersebut online. Proses ini dapat memperlambat eksekusi secara keseluruhan.
Solusi: Lakukan upgrade agen ke versi terbaru. Versi 1.7.9 ke atas mencakup optimasi untuk masalah ini.
Parameter instans untuk eksekusi satu kali
Di halaman Job Management, klik Actions di kolom Run once untuk menjalankan pekerjaan terjadwal satu kali. Di kotak dialog yang muncul, Anda dapat menentukan worker dan mengatur Instance Parameters. Ini adalah parameter opsional yang terutama digunakan untuk pengujian.
Parameter instans vs. parameter pekerjaan
Parameter instans dan parameter pekerjaan adalah dua konsep yang berbeda. Parameter yang diambil oleh kode Anda ditentukan oleh logika bisnis Anda.
Mendapatkan parameter pekerjaan atau parameter instans
Kode berikut menunjukkan cara mendapatkan parameter tersebut:
@Component
public class JavaDemoProcessor extends JavaProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger("schedulerxLog");
@Override
public ProcessResult process(JobContext jobContext) throws InterruptedException {
LOGGER.info(JSON.toJSONString(jobContext));
// Get job parameters
String jobParameters = jobContext.getJobParameters();
// Get instance parameters
String instanceParameters = jobContext.getInstanceParameters();
LOGGER.info("Job parameters: " + jobParameters);
LOGGER.info("Instance parameters: " + instanceParameters);
return new ProcessResult(InstanceStatus.SUCCESS);
}
}Mengambil parameter instans dengan fallback ke parameter pekerjaan
Kode berikut menunjukkan detailnya:
@Component
public class JavaDemoProcessor extends JavaProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger("schedulerxLog");
@Override
public ProcessResult process(JobContext jobContext) throws InterruptedException {
String params = null;
if (StringUtils.isNotBlank(jobContext.getInstanceParameters())) {
params = jobContext.getInstanceParameters();
} else {
params = jobContext.getJobParameters();
}
LOGGER.info("JavaDemoProcessor params:{}", params);
return new ProcessResult(InstanceStatus.SUCCESS);
}
}