8

我需要在我们的网站上提供行动/事件的安排。一个废话类比可能是一个日历系统,其中一个人添加了一个日历项目,并且当日期/时间被“点击”时,就会触发一些逻辑(例如计算报告)。

我可能有数百甚至数千个由我的客户输入的预定事件。当客户输入要安排的内容时,我会将该信息保存到数据库中。然后我猜我会在某处添加一个事件/作业,其中将包含数据库表主键。当要触发事件时,我将从数据库中获取该信息,然后执行逻辑。完毕。

有哪些常见的解决方案来处理这个问题?

我正在使用 .NET 3.5 SP1。DB 是 Sql Server 2008。UI 将是基于网络的。

我不确定人们是否使用 MSMQ?还是 Sql Server 内置的东西?或者一些带有 NT 服务的开源库(例如Quartz.NET )。服务器将是windows 2008标准版。

另外 - 请不要建议使用等效的 cron 作业或任何命令行脚本等。

最后,这是次要目标..我很想把它扔到天蓝色上,以供嘘声和咯咯笑...那也可能吗?这只是一个愿望清单的想法。如果解决方案比使用 Azure 更容易,我更愿意在专用盒子上进行。

干杯:)

编辑:需要触发事件时处理的逻辑是后台作业。不需要用户界面。

4

8 回答 8

4

Workflow Foundation可以做到这一点。使用延迟活动,将 TimeSpan 设置为 (DesiredTimeOfExecution - Now)。对于更大规模的系统,将 UnloadOnIdle 设置为 true,待处理的工作流将一直持续到需要为止。

这是延迟活动的一个非常简单的示例

WF 是免费的,包含在 .NET Framework 3.0 中。

于 2009-06-19T05:08:28.027 回答
2

您想要的是 SQL Server 服务代理。

您可以进行定时数据库访问以查询日历数据等。它是基于消息的,比 MSMQ 更强大,不需要轮询,如果您需要,可以在分布式环境中使用。对我有用!

您将点击一个存储过程,将您的事件信息放在数据库中的 SSB 队列中。您将在将来给该消息一个时间来唤醒并处理另一个存储过程,该过程获取您的事件数据并放入执行“外部激活”的拾取队列中。EA 向指向控制台应用程序的 Windows 服务发送通知。该控制台应用程序从拾取队列中获取事件信息。现在,您可以在您想要的准确时间获得您的事件数据。在控制台应用程序中随心所欲地处理它。

有一个学习曲线,但如果您需要 SQL Service Broker 提供的可靠性、灵活性和可伸缩性,那么它是非常值得的。以下是一些帮助您入门的链接。

这是一个比较:SQL Service Broker 与 MSMQ

不幸的是,SO 只允许我发布一个链接。否则,我可以为您指出更多资源,以帮助您开始使用 SSB。

希望这可以帮助!

于 2009-06-19T05:28:35.350 回答
2

Quartz.NET 可能也可以很好地处理这些要求。我看到的好处是设置调度程序(CronTrigger + 日历)的各种方式以及将您的工作放在可测试代码的小单元(工作)中的能力。

Quartz.NET 还为您提供了所需的分发和故障转移集群功能。一个不错的功能也是每个触发器可配置的失火处理设置,让您有机会对失火和调度程序停机时间做出反应。

SQL Service Broker 似乎有没有轮询的好处,我想知道这是否会成为问题,但代理的缺点是听起来有点复杂(至少从我上面读到的描述来看)。

只是我有偏见的 0.02 美元。

于 2009-06-30T23:16:50.620 回答
1

一种选择可能是创建一个 SQL 作业,以您拥有的任何最细粒度的时间间隔运行,然后处理所有事件。

如果您想要 .NET 和 SQL Server 世界中最好的,您可以使用 SQL 作业并调用托管代码。我对这个解决方案没有任何经验,所以如果我提供的资源不是很全面,我会提前道歉。

如果任务非常复杂,并且您不想在 SQL Server 上加载程序集,或者您只是不喜欢他们的调度系统,那么我建议使用带有第三方调度程序插件的 .NET Windows 服务。就个人而言,如果所有代码都可以保存在一个存储过程或一系列存储过程中,我会做一份工作,因为我认为它更容易管理并且已经为你完成了很多工作。

编辑

我刚刚注意到一个解释粒度的评论。如果您需要每分钟执行一些操作,那么 .NET 服务解决方案可能会更容易,因为您可能必须实现某种多线程解决方案。

于 2009-06-19T02:04:57.120 回答
1

您将需要一个作业调度程序和一个作业管理器,因为您的粒度很小,并且您必须能够先验地知道在给定分钟内发生的所有作业是否会在下一分钟完成。

这使调度程序的工作变得容易。您应该有一个存储您的作业的数据库表,并且每分钟都有一个作业调度程序服务转到该表并选择需要完成的作业。

它将使用作业经理将这些作业排入队列。您可以使用另一个表或事务队列来排队您的工作。您的作业管理器服务将监视作业队列。您可以自己滚动或使用BizTalk来监控作业队列并启动编排或工作流。它将一个一个地从队列中拉出任务,执行任务并更新数据库中的作业状态。

您的问题将是可伸缩性,具体取决于用户数量、他们排队的任务数量以及每个任务允许的密集程度(时间、内存、cpu 等)。如果我是你,我会推迟 1 分钟的时间粒度并将其推到 5 分钟。你需要在下午 1:38 完成哪些你不能等到下午 1:40 的事情?:)

于 2009-06-19T02:24:17.250 回答
1

这已经是 StackOverflow 上讨论的问题。请通过asp.net中的Need job scheduler

您忘记在问题中添加最重要的信息 - ASP.Net

它描述了一个用于 ASp.Net Web 应用程序的调度程序框架,它可以像服务一样运行,并为您提供一个定期调用的方法,然后您可以触发逻辑来加载事件,使用计时器对有效事件进行排队。

此外,这是所有替代品中最便宜的。希望这是你需要的。

于 2009-06-19T04:17:04.343 回答
0

这在一定程度上取决于系统的性质。假设事件的完整定义存储在数据库中:

  • 如果事件需要在 Web UI 中引起某些事情,则在更新时检查表中是否有“发生”的条目,并将适当的视觉指示器/屏幕/弹出窗口添加到下一个 Web 请求输出。
  • 如果您的事件与后台处理有关,最简单的解决方案是编写一个单独的独立 .NET 应用程序,该应用程序轮询数据库事件表中的新记录,并按时检查以查看发生了哪些事件。如果某些事件导致长时间运行的进程等,您可以花哨并涉及线程,但这将是基本设计。(只有在必须时才使用线程......轮询表的简单单线程应用程序将是最强大的)
于 2009-06-19T01:19:00.863 回答
0

然后我猜我会在某处添加一个事件/作业,其中将包含数据库表主键。当要触发事件时,我将从数据库中获取该信息,然后执行逻辑。

我不知道常见的解决方案是什么,但是,重新发明轮子,我想在事件时间创建一个数据库聚集索引,所以我可以每分钟轮询一次数据库,语句如下......

SELECT * FROM Events WHERE Events.Time < next_minute
于 2009-06-19T02:07:50.497 回答