2010-12-21 87 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

相关问题