2011-02-05 46 views
39

Có ai có thể tư vấn ở đây không? Tôi có một tình huống mà người dùng sẽ gửi yêu cầu khai thác dữ liệu một cách tương tác thông qua Java JSP và servlet đến một ứng dụng của tôi sẽ tự động làm việc ra các quy tắc kết hợp về dữ liệu và hơn thế nữa. Khi một công việc như vậy có thể mất một lúc, tôi đang nghĩ về một số quá trình trên máy chủ để chạy một yêu cầu như vậy trong nền để nó không 'khóa' phiên và có thể sử dụng lượng lớn máy chủ bộ nhớ gây thiệt hại cho hệ thống.Chạy một chương trình Java nền trong Tomcat

Khi hệ thống được tạo thành từ một loạt các Java JSP và các servlet đang chạy trong một thùng chứa Tomcat trên cơ sở dữ liệu MySQL, bất cứ ai có thể tư vấn một cách chuyển tiếp không?

Cảm ơn

Ông Morgan

+0

bạn đang mong đợi để đưa ra một phản ứng trở lại? Ngoài ra, Tomcat sử dụng threadpools có thể mở rộng khi cần thiết để phục vụ nhiều yêu cầu đồng thời. –

+0

Bạn có cần hiển thị kết quả của "yêu cầu khai thác dữ liệu" cho người dùng (hoặc ít nhất là thông báo cho họ về công việc đã hoàn thành) không? Và làm thế nào để bạn cần phải làm điều đó? –

+0

Tôi đã nghĩ rằng khi công việc kết thúc, người dùng có thể được gửi email để nói rằng kết quả có sẵn. –

Trả lời

5

Tôi nghĩ rằng thạch anh lên lịch sẽ có thể thực hiện những gì bạn muốn làm ở đây. Dưới đây là một số trong số examples from Quartz. Sử dụng điều này, bạn có thể bắt đầu một cron mà nhanh chóng thăm dò ý kiến ​​để xử lý các yêu cầu đến (s). Tôi thực sự đã làm điều đó cho một trong những dự án của tôi.

+0

Tôi sử dụng Quartz ở những nơi khác trong hệ thống cho các công việc theo lịch trình hàng giờ nhưng đó là một khả năng. –

+3

Quartz là một cuộc gọi tốt. Nó sẽ làm "Chạy công việc một lần, bây giờ" khá tốt.Ưu điểm khác là nó sẽ cho bạn khả năng khởi động lại. Khi bạn bắt đầu công việc, thạch anh có thể "lưu" yêu cầu và bắt đầu lại công việc nếu hệ thống bị hỏng. Bạn nhận được tất cả những gì "miễn phí", và kể từ khi bạn đã có nó, bạn đã biết làm thế nào để sử dụng nó. Tại sao thêm bộ mới để bạn ngăn xếp nếu bạn không phải? –

+0

@Will: +1 ... cũng nói. :) – limc

0

lẽ JMS là những gì bạn thực sự tìm kiếm tuy nhiên nó đòi hỏi nỗ lực nhiều để sử dụng trên Tomcat vì nó chỉ là Servlet Container. Bạn có thể chuyển sang eigher AppServer thực như Glassfish hoặc JBoss hoặc thêm chức năng JMS để Tomcat bằng cách riêng của bạn (sau đây liên kết)

http://blogs.captechconsulting.com/blog/jairo-vazquez/tomcat-and-jms

48

Sử dụng một ExecutorService. Có một vài điều bạn nên làm mặc dù, đánh dấu chủ đề như là một chủ đề daemon vì vậy nó atleast sẽ không tie tomcat trong các kịch bản lỗi, và bạn nên ngừng thực thi khi bối cảnh servlet của bạn bị phá hủy (ví dụ: khi bạn redeploy hoặc ngừng ứng dụng của bạn để làm điều này, sử dụng một ServletContextListener:.

public class ExecutorContextListener implements ServletContextListener { 
    private ExecutorService executor; 

    public void contextInitialized(ServletContextEvent arg0) { 
     ServletContext context = arg0.getServletContext(); 
     int nr_executors = 1; 
     ThreadFactory daemonFactory = new DaemonThreadFactory(); 
     try { 
      nr_executors = Integer.parseInt(context.getInitParameter("nr-executors")); 
     } catch (NumberFormatException ignore) {} 

     if(nr_executors <= 1) { 
     executor = Executors.newSingleThreadExecutor(daemonFactory); 
     } else { 
     executor = Executors.newFixedThreadPool(nr_executors,daemonFactory); 
     } 
      context.setAttribute("MY_EXECUTOR", executor); 
     } 

    public void contextDestroyed(ServletContextEvent arg0) { 
     ServletContext context = arg0.getServletContext(); 
     executor.shutdownNow(); // or process/wait until all pending jobs are done 
    } 

} 
import java.util.concurrent.Executors; 
import java.util.concurrent.ThreadFactory; 

/** 
* Hands out threads from the wrapped threadfactory with setDeamon(true), so the 
* threads won't keep the JVM alive when it should otherwise exit. 
*/ 
public class DaemonThreadFactory implements ThreadFactory { 

    private final ThreadFactory factory; 

    /** 
    * Construct a ThreadFactory with setDeamon(true) using 
    * Executors.defaultThreadFactory() 
    */ 
    public DaemonThreadFactory() { 
     this(Executors.defaultThreadFactory()); 
    } 

    /** 
    * Construct a ThreadFactory with setDeamon(true) wrapping the given factory 
    * 
    * @param thread 
    *   factory to wrap 
    */ 
    public DaemonThreadFactory(ThreadFactory factory) { 
     if (factory == null) 
      throw new NullPointerException("factory cannot be null"); 
     this.factory = factory; 
    } 

    public Thread newThread(Runnable r) { 
     final Thread t = factory.newThread(r); 
     t.setDaemon(true); 
     return t; 
    } 
} 

bạn sẽ có thêm người nghe bối cảnh để web.xml của bạn, nơi bạn cũng có thể chỉ định số lượng bài bạn sẽ muốn chạy công việc nền:

<listener> 
    <listener-class>com.example.ExecutorContextListener</listener-class> 
    </listener> 

Bạn có thể truy cập vào người thi hành từ servlet của bạn và gửi công ăn việc làm với nó:

ExecutorService executor = (ExecutorService)getServletContext().getAttribute("MY_EXECUTOR"); 
... 
executor.submit(myJob); 

Nếu bạn đang sử dụng Spring, tất cả điều này có lẽ có thể được thực hiện ngay cả simpler

+0

Làm thế nào một chủ đề không phải daemon sẽ ràng buộc tomcat trong một kịch bản lỗi? –

+0

Tôi đã đi xuống con đường này, nhưng tôi lo ngại về việc có thể phụ thuộc và duyên dáng tắt máy ExecutorService của tôi khi tomcat tắt. Tôi không thể mất những gì đang thực hiện. Rõ ràng bạn không thể phụ thuộc vào ServletContextListener. Xem http://stackoverflow.com/questions/1549924/shutdown-hook-for-java-web-application và http://stackoverflow.com/questions/11443133/shutdown-hook-in-tomcat-necessary-not-running –

+0

@nos, sau đó myJob Runnable phải có phương thức chạy như 'while (true) {Thread.sleep (1000); // làm điều gì đó khác ..} '.không phải?] –

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