【问题标题】:How to run a time consuming task on startup in a web application while deploying it如何在部署 Web 应用程序时在启动时运行一项耗时的任务
【发布时间】:2013-08-29 14:16:57
【问题描述】:

我们在服务器启动或应用程序部署时遇到了初始化缓存的问题。初始化缓存涉及

  1. 查询数据库以获取项目列表
  2. 为每个项目进行 rmi 调用
  3. 收听 JMS 队列/主题上的数据
  4. 构造缓存

这个初始化过程在启动代码中。所有这些都需要大量时间,因为部署需要大量时间或服务器启动时间正在增加。

所以我的建议是在启动时创建一个线程并在其中运行初始化代码。我编写了一个示例应用程序来演示它。

它涉及一个 ServletContextListener,一个过滤器。在侦听器中,我正在创建一个新线程,HeavyProcess 将在其中运行。当它完成时,将触发过滤器正在侦听的事件。收到事件后,过滤器将允许传入的 http 请求。在此之前,过滤器会将所有客户端重定向到默认页面,该页面显示应用程序正在初始化的消息。

我提出了这种方法,但很少有人提出担忧。

  1. 理想情况下,我们不应该创建线程,因为处理线程会很困难。

我的问题是为什么我们不能在 Web 应用程序中创建这样的线程。

如果这不好,那么最好的方法是什么?

【问题讨论】:

  • 请澄清:servlet container only 或 EJBs allowed 的解决方案?哪个应用服务器(包括版本)?
  • 我们正在使用 EJB 3.0 和 Glassfish 3.1.2.2 应用服务器。到目前为止,我们一直在使用 @Startup 注释,这延迟了部署。我使用 servlet api 给出了上述解决方案。

标签: multithreading jakarta-ee webserver


【解决方案1】:

如果您可以使用托管线程,请避免使用非托管线程。容器无法控制非托管线程和非托管线程survive重新部署,如果您没有正确终止这些。所以你必须注册非托管线程,并以某种方式终止它们(这也不容易,因为你必须小心处理竞争条件)。


所以一种解决方案是使用@Startup,类似这样:

@Schedule(second = "*/45", minute = "*", hour = "*")
protected void asyncInit(final Timer timer) {
    timer.cancel();

    // Do init here

    // Set flag that init has been completed
}

我在这里了解了这个方法:Executing task after deployment of Java EE application

因此,这为您提供了一个异步托管线程,并且@PostConstruct 不会延迟部署。注意timer.cancel()。


看看你的实际问题:我建议使用支持“热启动”的缓存。

例如,Infinispan 支持缓存存储,以便缓存内容在重新启动后仍然存在。如果您有集群,也有分布式或复制缓存模式。

JBoss 7 嵌入了 Infinispan(它是同一个 JVM 中的集成服务),但它也可以独立运行。

另一个候选者是 Redis(任何其他具有持久性的键/值存储也可以)。

【讨论】:

  • 您好,感谢您的帮助。基本上我使用了一个无状态的ejb并用@Startup注释它,@Schedule的方法之一。初始化完成后,我将触发一个过滤器侦听的事件并设置一个允许请求继续的标志。它现在可以工作了。
【解决方案2】:

一般来说,在 Java EE 环境中创建非托管线程是个坏主意。您将在非托管线程中丢失容器托管事务、用户上下文和更多 Java EE 概念。此外,如果您的线程处理不合适,非托管线程可能会在关闭时阻塞容器。

您使用的是哪个 Java EE 版本?或许您可以使用 Servlet 3.0 的异步功能?

或者在启动时调用异步 EJB 来完成繁重的工作 (@PostConstruct)。然后,该调用将在其工作完成时设置一个标志。

【讨论】:

  • 为什么创建非托管线程是个坏主意?我的一所高级大学也说了同样的话,但不能证明他的回答是正确的。我想知道。我们正在使用 Java EE 6。我将阅读异步 EJB 并检查它如何适合我们的问题。谢谢。
  • 再看看答案。我修改了为什么非托管线程不好的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-10
  • 2016-12-16
  • 2011-08-06
  • 1970-01-01
  • 2023-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多