2010-02-12 33 views
19

Tôi đã phát triển một ứng dụng web bằng cách sử dụng servlet và JSP. Tôi không sử dụng bất kỳ khung công tác nào, thay vì sử dụng khuôn khổ MVC đã được sản xuất tại nhà riêng của tôi. Tôi đang sử dụng MySQL như một phụ trợ.chạy nhiệm vụ định kỳ ở phía máy chủ cho trang web servlet JSP MVC

Tôi muốn làm như sau:

  1. Dọn dẹp một số dữ liệu từ cơ sở dữ liệu mỗi giờ
  2. Tạo và lưu trữ số liệu về dữ liệu mỗi 15 phút trong một tập tin XML đâu đó

Vấn đề là: hiện tại tất cả các mã của tôi chạy là kết quả của yêu cầu nhận được từ một khách hàng.

Làm cách nào để chạy tác vụ định kỳ ở phía máy chủ?

Một giải pháp mà tôi có ngay bây giờ là tạo một chuỗi trong hàm init của bộ điều khiển. Có sự lựa chọn nào khác không?

Trả lời

41

Bạn có thể sử dụng ServletContextListener để thực thi một số khởi tạo khi khởi động webapp. Cách API Java chuẩn để chạy các tác vụ định kỳ sẽ là kết hợp của TimerTimerTask. Dưới đây là một ví dụ Kickoff:

public void contextInitialized(ServletContextEvent event) { 
    Timer timer = new Timer(true); 
    timer.scheduleAtFixedRate(new CleanDBTask(), 0, oneHourInMillis); 
    timer.scheduleAtFixedRate(new StatisticsTask(), 0, oneQuartInMillis); 
} 

nơi có nghĩa vụ cả hai có thể trông giống như:

public class CleanDBTask extends TimerTask { 
    public void run() { 
     // Implement. 
    } 
} 

Sử dụng Timer được tuy nhiên không được khuyến khích trong Java EE. Nếu tác vụ ném một ngoại lệ, thì toàn bộ chuỗi Timer bị giết và bạn về cơ bản cần phải khởi động lại toàn bộ máy chủ để nó chạy lại. Các Timer cũng nhạy cảm với những thay đổi trong đồng hồ hệ thống.

Cách mới hơn và mạnh mẽ hơn java.util.concurrent sẽ là kết hợp của ScheduledExecutorService và chỉ Runnable. Dưới đây là một ví dụ Kickoff:

private ScheduledExecutorService scheduler; 

public void contextInitialized(ServletContextEvent event) { 
    scheduler = Executors.newSingleThreadScheduledExecutor(); 
    scheduler.scheduleAtFixedRate(new CleanDBTask(), 0, 1, TimeUnit.HOURS); 
    scheduler.scheduleAtFixedRate(new StatisticsTask(), 0, 15, TimeUnit.MINUTES); 
} 

public void contextDestroyed(ServletContextEvent event) { 
    scheduler.shutdownNow(); 
} 
+2

Chỉ muốn thêm vào câu trả lời tuyệt vời BalusC rằng '' scheduleAtFixedRate' và 'phương pháp scheduleWithFixedDelay' ScheduledExecutorService' sẽ ngăn chặn hành trong tương lai nếu ngoại lệ được bắt gặp trong một hoạt động. Vì vậy, hãy nhớ xử lý ngoại lệ của bạn. 'Nếu bất kỳ việc thực hiện nhiệm vụ nào gặp phải một ngoại lệ, các lệnh xử lý tiếp theo sẽ bị chặn. ' – dvd

Các vấn đề liên quan