如何在部署Web应用程序时在启动时运行耗时的任务 [英] How to run a time consuming task on startup in a web application while deploying it

查看:197
本文介绍了如何在部署Web应用程序时在启动时运行耗时的任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

we are facing an issue with initializing our cache at server startup or application deployment. Initializing the cache involves


  1. 查询数据库以获取项目列表

  2. 进行rmi调用对于每个项目

  3. 收听JMS队列/主题上的数据

  4. 构建缓存

  1. Querying a database to get the list of items
  2. Making an rmi call for each item
  3. Listening to the data on a JMS queue/topic
  4. Constructing the cache

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

This initialization process is in startup code. All this is taking lot of time due to which the deployment is taking lot of time or server start time is increasing.

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

So what I proposed is to create a thread in the startup and run the initialization code in it. I wrote a sample application to demonstrate it.

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

It involves a ServletContextListener, a filter. In the listener I am creating a new thread in which the HeavyProcess will run. When it finishes an event will be fired which the filter will be listening. On receiving the event the filter will allow incoming http requests. Until then the filter redirects all clients to a default page which shows a message that the application is initializing.

我提出了这种方法并且提出了一些问题。

I presented this approach and few concerns were raised.


  1. 我们不应该理想地创建一个线程,因为处理线程会很困难。

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

My question is why cant we create a thread like these in web applications.

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

If this is not good, then what is the best approach?

推荐答案

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

If you can use managed threads, avoid unmanaged ones. The container has no control over unmanaged threads, and unmanaged threads survive redeployments, if you do not terminate these properly. So you have to register unmanaged threads, and terminate these somehow (which is not easy as well, because you have to handle race-conditions carefully).

所以一个解决方案是使用 @Startup ,类似这样的事情:

So one solution is to use @Startup, and something like this:

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

    // Do init here

    // Set flag that init has been completed
}

我在这里了解了这个方法:部署Java EE应用程序后执行任务

I have learned about this method here: Executing task after deployment of Java EE application

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

So this gives you an async managed thread, and deployment will not be delayed by @PostConstruct. Note the timer.cancel().

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

Looking at your actual problem: I suggest using a cache which supports "warm starts".

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

For example, Infinispan supports cache stores so that the cache content survives restarts. If you have a cluster, there are distributed or replicated caching modes as well.

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

JBoss 7 embeds Infinispan (it's an integrated service in the same JVM), but it can be operated independently as well.

另一个候选人是 Redis (任何其他具有持久性的键/值存储也会这样做。)

Another candidate is Redis (and any other key/value store with persistence will do as well).

这篇关于如何在部署Web应用程序时在启动时运行耗时的任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆