Pertanyaan Bagaimana cara menjalankan tugas latar belakang dalam aplikasi web berbasis servlet?


Saya menggunakan Java dan saya ingin menjaga servlet terus berjalan di aplikasi saya, tetapi saya tidak mendapatkan cara melakukannya. Servlet saya memiliki metode yang memberikan jumlah pengguna dari basis data setiap hari serta jumlah total pengguna dari seluruh basis data. Jadi saya ingin menjaga servlet terus berjalan untuk itu.


76
2018-01-14 12:39


asal


Jawaban:


Masalah Anda adalah bahwa Anda salah memahami tujuan dari servlet. Ini berniat untuk bertindak atas permintaan HTTP, tidak lebih. Anda hanya menginginkan tugas latar belakang yang berjalan sekali setiap hari.

EJB tersedia? Menggunakan @Schedule

Jika lingkungan Anda mendukung EJB (misalnya WildFly, JBoss AS / EAP, TomEE, GlassFish, dll), kemudian gunakan @Schedule sebagai gantinya.

@Singleton
public class BackgroundJobManager {

    @Schedule(hour="0", minute="0", second="0", persistent=false)
    public void someDailyJob() {
        // Do your job here which should run every start of day.
    }

    @Schedule(hour="*/1", minute="0", second="0", persistent=false)
    public void someHourlyJob() {
        // Do your job here which should run every hour of day.
    }

    @Schedule(hour="*", minute="*/15", second="0", persistent=false)
    public void someQuarterlyJob() {
        // Do your job here which should run every 15 minute of hour.
    }

} 

Ya, itu benar-benar semua. Penampung akan secara otomatis mengambil dan mengelolanya.

EJB tidak tersedia? Menggunakan ScheduledExecutorService

Jika lingkungan Anda tidak mendukung EJB (yaitu bukan server Java EE yang sebenarnya, misalnya Tomcat, Jetty, dll.), Gunakan ScheduledExecutorService. Ini dapat dimulai oleh a ServletContextListener. Berikut contoh hasil awal:

@WebListener
public class BackgroundJobManager implements ServletContextListener {

    private ScheduledExecutorService scheduler;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
        scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
        scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        scheduler.shutdownNow();
    }

}

Di mana kelas pekerjaan terlihat seperti ini:

public class SomeDailyJob implements Runnable {

    @Override
    public void run() {
        // Do your daily job here.
    }

}
public class SomeHourlyJob implements Runnable {

    @Override
    public void run() {
        // Do your hourly job here.
    }

}
public class SomeQuarterlyJob implements Runnable {

    @Override
    public void run() {
        // Do your quarterly job here.
    }

}

Jangan pernah berpikir untuk menggunakan java.util.Timer/java.lang.Thread di Java EE

Tidak pernah langsung digunakan java.util.Timer dan / atau java.lang.Thread di Java EE. Ini adalah resep untuk masalah. Penjelasan yang terperinci dapat ditemukan dalam jawaban terkait JSF ini pada pertanyaan yang sama: Pemijahan benang dalam kacang JSF dikelola untuk tugas yang dijadwalkan menggunakan timer.


173
2018-01-14 13:45



Saya akan menyarankan menggunakan perpustakaan seperti kuarsa untuk menjalankan tugas secara berkala. Apa yang benar-benar dilakukan servlet? Ini mengirimi Anda laporan?


3
2018-01-14 13:08



Anda dapat menggunakan cron4j. http://www.sauronsoftware.it/projects/cron4j/manual.php


1
2017-12-22 08:13



Terapkan dua kelas dan panggil startTask() di main.

public void startTask()
{
    // Create a Runnable
    Runnable task = new Runnable() {
        public void run() {
            while (true) {
                runTask();
            }
        }
    };

    // Run the task in a background thread
    Thread backgroundThread = new Thread(task);
    // Terminate the running thread if the application exits
    backgroundThread.setDaemon(true);
    // Start the thread
    backgroundThread.start();
}

public void runTask()
{
    try {
        // do something...         
        Thread.sleep(1000);

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

1
2018-03-05 17:49



Dalam sistem produksi yang mungkin memiliki beberapa kontainer non-jee yang sedang berjalan. Gunakan scheduler perusahaan anot seperti penjadwal Quartz yang dapat dikonfigurasi untuk menggunakan database untuk tugas maamgememt.


0
2018-02-21 15:31