2010-12-21 39 views
2

HTTP POST(由應用程序生成,而不是由用戶生成)之後,我想發送電子郵件。我收到了電子郵件發送程序,但我不確定Java webapp服務器是如何工作的。如何處理doGet或doPost中潛在的長時間操作?

我特別擔心超時,我想知道我是否以某種方式阻止了一個重要的線程。

如果我這樣做了以下內容:

@Override 
    public void doPost(
      final HttpServletRequest req, 
      final HttpServletResponse resp 
    ) throws IOException, ServletException { 
     final PrintWriter pw = resp.getWriter(); 
     pw.write(...); 
     pw.flush(); 
     pw.close(); 
     // Here I'm sending an email, this can potentially 
     // block until the email send procedure times out 
     // (the timeout is set to 5 seconds) 
     sendEmail(...); 
    } 

如果電子郵件服務器關閉,該線程將阻塞,直到我sendEmail超時(超時我設置爲幾秒鐘)。

哪個線程然後阻塞?我的意思是,顯然我意識到我阻止正在處理這個POST的線程,但這是一個問題?這個線程應該接下來做什麼?

我讀過,我不應該從Java webapp服務器創建新線程,所以我認爲我不應該做下面的權利?

Thread t = new Thread(new Runnable() { 
     public void run() { 
      sendEmail(); 
     } 
    }); 
    t.start(); 

請注意,我的問題是不特定於電子郵件發送:我想了解在一個Java Web應用程序每次要照顧你計劃一個GET或後做可能阻塞/長操作POST。

回答

2

在servlet中啓動一個線程是可以的,你只需要非常小心地確定它在servlet被取消部署時會死掉。

最簡單的方法是在servlet啓動時創建一個java.util.concurrent.ExecutorService,並在servlet銷燬時將其關閉。然後,您可以將您的電子郵件作業提交給執行者服務,並從doPost返回。請注意,如果在作業排隊後該servlet被銷燬,則可能不會發送一些電子郵件。

在代碼:

class EmailServlet extends HttpServlet { 
    private ExecutorService emailSender; 

    public void init() { 
     emailSender = Executors.newFixedThreadPool(1); 
    } 

    public void destroy() { 
     emailSender.shutdownNow(); 
    } 

    public void doPost(...) { 
     ... 
     emailSender.execute(new Runnable() {public void run() {sendEmail();}}); 
    } 
} 
1

我的建議:將您需要執行的任務(即在數據庫或隊列中)存儲在第二個進程的後臺進行處理,並使您的doPost/doGet儘快返回。用戶不想等。例如,您可以接收外部應用程序請求,將需要發送的電子郵件存儲在數據庫中或將其放入JMS隊列(許多應用程序服務器帶有JMS功能,但我從未使用它們),以及返回。其他進程可以讀取該數據庫/隊列併發送電子郵件而不阻止HTTP響應。

關於在您的web應用程序中使用線程,它可以工作,它可能是最簡單的解決方案,但它也可能有可伸縮性問題。如果你這樣做,請確保使用某種線程池(ExecutorService ...),因爲Web服務器/操作系統通常對線程數量有限制。

+0

比如我可以把所有帖子的電子郵件上的請求隊列,並有另一個(唯一的)線程出列他們,送他們。但這意味着我必須產生至少一個其他線程。這可以嗎? – NoozNooz42 2010-12-21 23:10:34

+0

在我的情況下,它不是用戶,而是另一個執行POST的應用程序。但是,無論如何,用戶發送這些POST的位置並不是用戶在關閉流後立即返回頁面的位置? (在嘗試發送電子郵件之前我會這樣做) – NoozNooz42 2010-12-21 23:11:51

相關問題