我的项目需要定期扫描数据库,并就特定问题通知管理员。例如:
我的节点(普通的旧窗口服务)目前正在使用Azure QueueClient执行其他分布式任务,所以我最初的想法是使用用同样的组件做一些事情。然而,事实证明这是相当有挑战性的(见下文)。
通过集思广益,我提出了以下可能的选择:
描述:在接收到任务后,消息处理程序将在将来为X排队一个新的消息集。
例如:
var client = QueueClient.Create("DetectErrors");
var options = /* ... */
client.OnMessage((message) => {
client.Send(new BrokeredMessage() {
ScheduledEnqueueTimeUtc = DateTime.Today.AddDays(1)
});
if (DetectStuffInDb())
{
SendEmail();
}
}, options)问题:如何发送第一条信息?这需要在没有挂起消息的情况下触发,并且只触发单个消息(如果所有节点都在同一时间启动,则每个节点不会触发一个消息)。
描述:使用Azure new作业访问我的WebApi上的一个端点,它将为一条新消息排队。(这方面的一个小小的派生就是使用Azure自动化+ Runbook来对消息进行排队)
问题:让这么多“啤酒花”来处理每一项任务似乎很奇怪。[WebJob] -> [WebApi] -> [Queue] -> [Node]。此外,这将使开发\测试变得有点困难,因为WebJob可能无法访问本地主机WebApi。
描述:使用Task.Delay在每个分布式节点上划分重复出现的任务&如果另一个节点目前正在处理该任务,请与DB验证。有点像
var id = Cmd("SELECT [Id] FROM [T]");
while (true)
{
var newId = Guid.NewGuid();
Cmd("UPDATE [T] SET [Id] = '<newId>' WHERE [Id] = '<id>'");
id = Cmd("SELECT [Id] FROM [T]");
if (newId == id)
{
if (DetectStuffInDb())
{
SendEmail();
}
}
await Task.Delay(x);
}问题:所有节点都需要对数据库进行大量查询。
发布于 2015-03-12 12:56:00
我的建议是不要过于复杂你的程序,试图容纳任务调度。当涉及到这些事情时,我通常更喜欢依赖cron或windows任务调度程序来处理何时的具体问题。这使您有可能只关注如何,您可以不必担心接口和所有这一切,以建立一个预定的任务。
只需创建一个简单的批处理文件来执行对服务器的请求,并安排它每天运行一次。我认为这是一个系统管理员必须处理的事情,当然不是你的典型用户,所以你可以让你的老板感到高兴,让你的老板在更短的时间内工作,并且仍然拥有你可能需要的所有功能。虽然这确实使您的程序操作系统依赖,但是使用cron实现相同的工作只需花费很少的工作,而且在您的情况下,这个讨论甚至是不相关的。
或者,您可以搜索提供此支持的库。无论如何,我强烈鼓励您抵制自己编写代码的诱惑。这类事情已经做了很多次了,如果你试图自己做,除了浪费时间,你可能会发现一些严重的问题,如果你幸运的话,不会让你被炒鱿鱼。不要冒险,也不要重新发明轮子。我个人的想法是,我们最好的程序员不是比你更好地编写算法的人,而是那些优雅地承认这些东西已经写好的人,他们必须小心地拼凑在一起。
请告诉我结果如何。:)
https://softwareengineering.stackexchange.com/questions/275975
复制相似问题