且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在部署Web应用程序时在启动时运行耗时的任务

更新时间:2023-10-16 18:11:16

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

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).