8

在 podcast #15 中,Jeff 提到他在 Twitter 上谈到了如何在后台运行常规事件,就好像它是一个正常的功能一样——不幸的是,我似乎无法通过 twitter 找到它。现在我需要做类似的事情,并将这个问题抛给大众。

我目前的计划是当第一个用户(可能是我)进入站点时,它会启动一个后台线程,等待分配的时间(每小时一次),然后启动阻止其他人的事件(我是一名 Windows 程序员,所以我认为在事件和 WaitOnMultipleObjects 方面)直到它完成。

Jeff 在 Asp.Net 中是如何做到的?他的方法是否适用于 Java web-app 世界?

4

5 回答 5

12

我认为为运行后台任务开发自定义解决方案并不总是值得的,因此我建议使用 Java 中的Quartz Scheduler

在您的情况下(需要在 Web 应用程序中运行后台任务),您可以使用分发中包含的 ServletContextListener 在Web 容器启动时初始化引擎

之后,您有多种可能开始(触发)您的后台任务(作业),例如,您可以使用日历或类似 cron 的表达式。在您的情况下,您很可能应该使用SimpleTrigger,它可以让您以固定的定期间隔运行作业。

作业本身也可以在 Quartz 中轻松描述,但是您没有提供有关您需要运行什么的任何详细信息,因此我无法在该领域提供建议。

于 2008-09-07T11:25:27.407 回答
5

如前所述,石英是一种标准解决方案。如果您不关心重启后后台任务的集群或持久性,您可以使用内置的 ThreadPool 支持(在 Java 5,6 中)。如果您使用ScheduledExecutorService,您可以将 Runnables 放入后台线程池中,等待特定时间后再执行。

如果您确实关心集群和/或持久性,您可以使用 JMS 队列进行异步执行,尽管您仍然需要一些延迟后台任务的方法(您可以使用 Quartz 或 ScheduledExecutorService 来执行此操作)。

于 2008-09-07T11:35:15.887 回答
3

Jeff 的机制是创建某种缓存对象,ASP.Net 会以某种间隔自动重新创建该对象 - 它似乎是 ASP.Net 特定的解决方案,因此在 Java 世界中可能对您(或我)没有多大帮助。

请参阅https://stackoverflow.fogbugz.com/default.asp?W13117

阿特伍德:嗯,我最初是在 Twitter 上问的,因为我只是想要一些轻量级的东西。我真的不想写一个 Windows 服务。我觉得那是带外代码。加上实际工作的代码实际上是一个网页,因为对我来说,这是一个网站上的逻辑工作单元是一个网页。所以,这真的就像我们正在回调网站,就像网站中的另一个请求,所以我认为它应该保持内联,我们提出的小方法是在 Twitter 上推荐给我的本质上是向应用程序缓存添加具有固定到期时间的内容,然后您有一个回调,因此当到期时它会调用某个完成工作的函数,然后您将其添加回具有相同到期时间的缓存中。所以,有一点,也许”

我的方法一直是让操作系统(即 Cron 或 Windows 任务调度程序)每隔一段时间加载一个特定的 URL,然后在该 URL 上设置一个页面来检查它的队列,并执行所需的任何任务,但我会有兴趣听听是否有更好的方法。

从文字记录来看,FogBugz 似乎也使用 Windows 服务加载 URL 方法。

Spolsky:所以我们有一个名为 heartbeat.asp 的特殊页面。而那个页面,无论何时你点击它,任何人都可以随时点击它:没有伤害。但是当该页面运行时,它会检查等待任务的队列,以查看是否有任何需要完成的事情。如果有什么需要做的,它会做一件事,然后再次查看该队列,如果还有其他事情要做,它会返回一个加号,它返回的整个网页只是一个带加号的字符在里面。如果没有其他事情要做,队列现在是空的,它返回一个减号。因此,任何人都可以调用它并多次点击它,您可以在您的网络浏览器中加载 heartbeat.asp,您点击 Ctrl-R Ctrl-R Ctrl-R Ctrl-R 直到您开始得到减号而不是加号。当你' 已经完成,FogBugz 将完成它需要做的所有维护工作。所以这是第一部分,第二部分是一个非常非常简单的 Windows 服务,它运行,它的全部工作是调用 heartbeat.asp,如果它得到一个加号,很快就会再次调用它,如果它得到一个减号调用再来一次,但暂时不会。所以基本上有一个一直在运行的 Windows 服务,它有一个非常非常非常简单的任务,只需点击一个 URL,然后查看它是否得到加号或减号,然后根据是否再次运行来调度它它有一个加号或减号。显然你可以在这个主题上做任何你想要的变化,例如,你实际上可以,而不是只返回一个加号或减号,你可以说“好的,在 60 秒内给我回电话”或“ 这样维护服务就可以运行了包含导致这些网页以一定的保证频率被调用的痒痒。在 heartbeat.asp 的网页中,有一段代码维护了一个需要完成的任务队列,并查看已经过去了多少时间,你知道,进行深夜维护,每 7 天删除所有旧消息已被标记为垃圾邮件和各种刚刚维护的后台任务。嗯,就是这样。这样维护服务就可以运行了包含导致这些网页以一定的保证频率被调用的痒痒。在 heartbeat.asp 的网页中,有一段代码维护了一个需要完成的任务队列,并查看已经过去了多少时间,你知道,进行深夜维护,每 7 天删除所有旧消息已被标记为垃圾邮件和各种刚刚维护的后台任务。嗯,就是这样。里面没有任何逻辑,它只包含导致这些网页以一定的保证频率被调用的挠痒痒。在 heartbeat.asp 的网页中,有一段代码维护了一个需要完成的任务队列,并查看已经过去了多少时间,你知道,进行深夜维护,每 7 天删除所有旧消息已被标记为垃圾邮件和各种刚刚维护的后台任务。嗯,就是这样。里面没有任何逻辑,它只包含导致这些网页以一定的保证频率被调用的挠痒痒。在 heartbeat.asp 的网页中,有一段代码维护了一个需要完成的任务队列,并查看已经过去了多少时间,你知道,进行深夜维护,每 7 天删除所有旧消息已被标记为垃圾邮件和各种刚刚维护的后台任务。嗯,就是这样。深夜维护和每 7 天删除所有已标记为垃圾邮件的旧邮件和各种仅维护后台任务。嗯,就是这样。深夜维护和每 7 天删除所有已标记为垃圾邮件的旧邮件和各种仅维护后台任务。嗯,就是这样。

于 2008-09-07T10:31:41.373 回答
2

我们将jtcron用于我们计划的后台任务。它运作良好,如果您了解 cron,它应该对您有意义。

于 2008-09-07T15:55:20.160 回答
1

这是他们在 StackOverflow.com 上的做法:

https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

于 2008-09-07T10:37:54.260 回答