在大型站点上服务后台任务


49

我们正在处理StackOverflow上一个有趣的问题。

我们有一堆小的“需要尽快完成的任务”。一个示例是更新“相关问题”列表。过去我们所做的是将这些任务附加到某些用户的页面加载中。

这从来都不是理想的,但并不是很明显。现在,SO已经超过了1,000,000个问号,那些不幸的用户开始感觉到它。

自然的解决方案是将这些任务实际推入后台。我正在考虑有两种广泛的方法可以做到这一点。

1.在IIS中作为自定义线程池/工作队列

基本上,我们启动了几个(非ThreadPool,以便不干扰IIS)线程,并使它们服务于我们将Funcs推入的某些集合。

这里的最大优点是简单性。我们不必担心会封送任何东西,也不必确保某些外部服务正常运行并做出响应。

我们还可以访问所有通用代码。

缺点是,我们不应该使用后台线程。我知道的反对意见都集中在饥饿的IIS(如果使用ThreadPool)和线程随机死亡(由于AppPool回收)的问题上。

我们已经有了现有的基础架构来使随机线程死亡成为非问题(基本上可以放弃检测任务的可能性),并且限制线程数量(并使用非ThreadPool线程)也不难。

我是否在IIS进程线程池/工作队列中缺少其他任何反对意见?

已移至StackOverflow,因为此处未真正解决。

2.作为服务

某些第三方解决方案或定制解决方案。

基本上,我们会将任务跨流程边界编组到某个服务,而不必理会它。大概我们是在某些代码中链接原始代码,或者将它们限制为原始SQL +连接字符串。

优点是这样做的“正确方法”。

缺点是我们要么只能做有限的工作,要么必须制定一些系统来使该服务与我们的代码库保持同步。我们还需要以某种方式挂钩所有监视和错误日志记录,这些都是通过“ In IIS”选项免费获得的。

服务方法还有其他好处或问题吗?

简而言之,是否存在无法预见和无法克服的问题,从而使方法1变得不可行,如果是的话,我们是否应该寻求方法2的良好第三方服务?


正确的方法是,当您决定走另一条路时,您会回顾并说我们应该以正确的方式进行操作。做出明智的选择。我对IIS世界还不够熟悉,无法对这个特定问题发表评论。
克里斯,

2
我很好奇,因为我有一个类似的场景(规模要小得多),我也只是piggy带了一些随机用户的不幸连接。我对最佳解决方案不甚了解,因此我将继续进行介绍。:-)
pc1oad1etter

7
我不明白为什么它不在StackOverflow上。这是工程上的权衡,而不是主观评估。您需要分析不同的方法,这都是客观的。只有当分析明确权衡了什么之后,它才有主观性,而且据我所知,您的问题不是“我应该找到更重要的东西,我的时间和服务器资源,还是我的用户时间? ' 或类似的东西。
Joren

@Kevin Montrose-从您的评论看来,您似乎在区分“需要尽快完成的需求”和“按间隔计划”。你能否解释为什么这是两个不同类型的,需要不同的图案/基础设施后台任务?
波特曼

@Portman-根本的区别在于,不能很快地完成“即将完成”的任务,我们确实需要等到知道需要完成这些任务后再进行。信封计算的某些结果表明,如果我们将“相关问题”查询(只是众多查询之一)移到“哑” cron选项卡上,则大约需要花费时间。一个星期的执行力可以解决所有问题。通常,我们还希望它们尽快运行(而不影响用户体验),而间隔任务的运行频率不超过5分钟一次(通常不那么频繁)。
凯文·蒙特罗斯

Answers:


17

几周前,我对SO 提出了类似的问题。简而言之,一段时间以来,我的方法是开发Windows服务。我将使用NServiceBus(本质上是MSMQ)将请求从Web应用程序封送至服务。我曾经使用WCF,但是要使分布式事务在WCF上正常工作总是让人感到痛苦。NServiceBus可以解决问题,我可以在事务中提交数据并创建任务,而不必担心我的服务当时是否已启动并正在运行。举一个简单的例子,如果我需要发送电子邮件(例如注册电子邮件),我将创建用户帐户并在事务中向Windows服务发出信号(发送电子邮件)。服务端的消息处理程序将提取消息并进行相应处理。

由于已经发布了ASP .NET 4.0和AppFabric,因此上述机制有许多可行的替代方案。回到上面提到的问题,我们现在有了AppFabric的AppInitialize(通过net.pipe)以及ASP .NET 4.0的自动启动功能,这些功能使将Windows Services开发为Web应用程序成为可行的选择。由于多种原因,我现在开始执行此操作(最大的原因是部署不再是一件麻烦事):

  1. 您可以在服务上开发Web UI(因为它作为Web应用程序运行)。这对于查看运行时正在发生的事情非常有用。
  2. 您的Web应用程序的部署模型将适用于您的服务应用程序。
  3. IIS提供了一些精巧的功能来处理应用程序故障(在某些方面类似于Windows服务)。
  4. Web开发人员(自然)对开发Web应用程序非常熟悉,大多数人在开发Windows Service时对最佳实践并不了解。
  5. 它提供了许多替代方法来公开API供其他应用使用。

如果您走这条路(请原谅我从原始文章中进行复制和粘贴),我肯定会考虑在单独的Web应用程序中运行后台逻辑。原因有很多:

  1. 安全性。UI可能有不同的安全模型,用于显示有关正在运行的后台进程的信息。除了操作团队之外,我不想将此UI公开给其他任何人。而且,Web应用程序可以以具有提升权限集的其他用户身份运行。
  2. 维修保养。能够将更改部署到托管后台进程的应用程序而不会影响用户对前端网站的使用,将是很棒的。
  3. 表现。将应用程序与处理用户请求的主站点分开意味着后台线程不会削弱IIS处理传入请求队列的能力。此外,如果需要,处理后台任务的应用程序可以部署到单独的服务器上。

这样做可以回到编组方面。WCF,NServiceBus / RabbitMQ / ActiveMQ等,香草MSMQ,RESTful API(认为MVC)都是选项。如果您使用的是Windows Workflow 4.0,则可以公开您的Web应用程序可以使用的主机终结点。

对我来说,用于服务的Web托管方法还算是陌生的,只有时间才能证明这是否是正确的选择。到目前为止到目前为止还不错。顺便说一句,如果您不想使用AppFabric(由于某种奇怪的原因,我不能,不支持Windows Server Web Edition),那么Gu的帖子中提到的自动启动功能就可以很好地工作。不过,远离applicationhost.config文件,该文章中的所有内容都可以通过IIS控制台(主服务器级别上的Configuration Editor)进行设置。

注意:我最初在此消息中发布了更多链接,但是,这是我对此交流的第一篇文章,仅支持一个链接!基本上有另外两个,让他们获得Google“ Windows服务之死...万岁AppFabric!” 和“ auto-start-asp-net-applications”。对于那个很抱歉。


使用单独的网站作为服务的基本思想是一个我从未考虑过的有趣的话题……
Kevin Montrose

Rohland,我可能在这里丢失了一些东西,但是您似乎是在说您正在从NServiceBus处理程序内部与Windows Service进行交互,然后该服务发送电子邮件。如果我是对的,请问为什么您不发送来自NServiceBus消息处理程序的电子邮件,而这很容易开发,测试和部署?
肖恩·基伦

该网站向Windows服务发送一条消息。Windows Service NServiceBus消息处理程序拾取消息并发送消息。本质上,这与您描述的过程相同。
罗兰

22

Windows中实际上有第三种方法来运行后台服务,这在UNIX世界中非常普遍。第三种方式是一项CRON运行您的基础架构的工作。在Windows中,这称为,task scheduler对于按计划运行代码非常普遍。要使用此功能,您将创建一个按预定时间表执行的命令行应用程序。这样做的好处是您不必担心进程是否像服务一样正常启动和运行,因为如果由于某种原因它失败了,它将在下次启动。

至于封送特定任务,您实际上只需要将这些任务存储在持久性二进制存储中。直到命令行应用程序从存储中选择它们并执行它们。过去,我使用Cassandra数据库作为会话状态提供程序来完成此任务,以便为Cassandra数据库中的特定用户填充后台任务,然后让命令行选择它们并为用户执行它们。

这可能不是典型的封送处理解决方案,但是它对我来说效果很好,并且事实证明这是一个非常优雅的解决方案,因为计划任务在关机,网络问题后仍然存在,而且任何机器都可以执行任务,因为它集中在中央存储。

无耻的晋升,但这是我的项目,而我刚刚简要介绍的解决方案是创建该项目的原因:http : //github.com/managedfusion/fluentcassandra/


2
我使用共享托管服务来执行此操作,因为我没有外壳访问权限。编写一个执行重要操作的PHP页面,然后执行一项cron作业,该作业定期使用wget或lynx加载该页面。这听起来像是在这种情况下可以工作的事物类型,并且非常简单,几乎不需要更改当前的工作方式。
莉吉特

多么简单的解决方案。它为我自己的项目激发了一些想法,而我什至没有考虑。另外,您还可以完全访问现有代码库。只需将控制台项目添加到解决方案中,然后引用现有项目。
Tim Murphy

10

Cron +网络应用

这是经过考验的设计,可以与Web场一起水平扩展,并确保您使用的是已知的Web技术堆栈

运作方式如下:

  1. 在Web应用程序中创建控制器/操作以处理计划的后台任务。按照惯例,我通常称呼我的http://mydomain.com/system/cron
  2. 为了安全起见,此操作应仅锁定到本地网络上经过身份验证的IP地址。
  3. 在单独的计算机上,安装Wget并设置“ 计划任务”以使wget从步骤1中获取资源。您可以根据需要使任务运行的频率(我通常选择30秒)。不要忘记将适当的cookie参数传递给Wget,以便对您的Web应用程序进行身份验证。
  4. 为了实现冗余,您还可以在第二台计算机上安装第二个计划的wget。

万岁!现在您有了一条将每30秒调用一次的路由。而且,如果处理该请求需要5分钟,那么没有人会在意,因为它不是用户页面请求的一部分。

cron行动最终看起来很简单:他有一个方法列表对某个频率执行。收到请求时,他会查看是否需要执行一个方法,然后调用适当的方法。这意味着您可以控制数据库中的日程表,在该数据库中,您可能已经有许多其他重要的站点配置数据。

更重要的是(对您而言),这意味着不必按固定的时间表调用您的工作。您可以编写想要确定何时执行方法的任何逻辑。

利弊

优点
  • 您已经非常擅长编写ASP.NET MVC代码,因此,您可以在编写其余解决方案的平台上编写后台任务。
  • 这些任务在与Web应用程序相同的上下文中运行,因此您可以共享缓存并利用已经存在的帮助程序方法
  • 如果您有wget获取负载平衡的 URI,那么现在您的后台任务也已实现负载平衡。
  • 同步部署 -您不必担心将Web应用程序与后台任务逻辑同步,因为它们都在同一部署中。
缺点
  • 多年以来,一些人告诉我这种设计是“高度耦合的”,但是当他们按下时,他们却无法阐明为什么这是一件坏事。

注意:如果有任何疑问或疑虑,请添加评论。我很高兴阐述。


7

我已经尝试并在当前应用程序中使用了几乎所有可能的方法。我开始做与您当前相同的操作,背对用户请求填充数据,然后将其缓存。我意识到这也不是一个好主意(尤其是当您扩展到多个Web服务器时,更多的用户会受到打击)。

我也有一个计划中的工作,它会在ASP.NET应用程序中命中URL-这是一个不错的解决方案,但是当您扩展到超过1台Web服务器时,它开始崩溃。

目前,我使用两种不同的方法,都使用Quartz.NET,这是一个很棒的小库。首先是Quartz.NET与ASP.NET一起在进程内运行,它是在global.asax中设置的,每隔几分钟运行一次。我用它来带外更新ASP.NET缓存,这是它作为ASP.NET的一部分运行的唯一原因。

第二个是我写了一个包装Quartz.NET的库DaemonMaster-它很容易将DLL放到目录中并使其在Windows服务中运行。我发现它有助于避免使用Windows Service的某些烦人的部分,并且还可以清理Quartz.NET api。通过DaemonMaster运行的服务具有两种不同的风格,第一种是需要每晚或每隔X分钟运行的作业。其他作业根据来自ASP.NET应用程序的数据进入队列。ASP.NET应用程序将JSON对象放在RabbitMQ上,服务轮询RabbitMQ,然后处理数据。

基于此,我建议您使用Windows服务(并检出DaemonMaster),并在需要时使用RabbitMQ之类的队列将数据从ASP.NET应用程序传递到服务-在所有这些解决方案中,它发挥了最佳作用。如果您正在加载缓存,则在ASP.NET中运行是有意义的,否则我认为不会。


6

我会以正确的方式进行操作,并运行Windows服务来监视“队列”。我之所以说“排队”,是因为使用MSMQ进行编程类似于将热门扑克插入您的眼球。

我已经爱上了Delayed :: Job in Rails 的简单性,并且在.NET中可以轻松完成类似的操作。

基本上,您添加了任何一种SomethingOperation(具有某种Perform()方法的东西)。然后,只需序列化相关参数,为其赋予优先级,某种默认重试行为并将其填充到数据库中即可。

您的服务将仅对此进行监视并处理队列中的作业。


序列化相关参数并不是真正的“公正”,几乎是“全部”。对于分开的处理方法,这是我最大的保留意见之一
凯文·蒙特罗斯

是的,这与我使用的解决方案相同,但是我将整个对象作为二进制文件序列化到数据库中,然后将它们拉出执行。我将Cassandra用作我的持久性存储,并使用Task Scheduler作为将运行和执行任务的命令行应用程序的CRON Scheduler。
尼克·贝拉迪

我们首先在消息中包含一个简单的数据,最后抛出整个对象。它仍然表现出色。我认为分离还有其他好处。
内森·帕尔默

@Kevin-如果我们只有一些拥有很多序列化历史的人……
Marc Gravell

4

我们对服务总线/消息队列/服务方法非常满意。基本架构是这样的。

网站发送消息到队列

bus.Send(new ProjectApproved()); // returns immediately

Windows服务在自己的时间内接收和处理消息

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Do something "offline"
   }
}

优点是用户连接的前端服务也没有延迟。Windows服务可以关闭并升级,而不会中断主站点。再加上它非常快

如果您不能在消息中存储所有数据,则可以随时存储并在以后检索。我建议使用诸如RavenDBMongoDB之类的文档存储机制,在其中无需更改即可直接存储您的类。

网站发送消息到队列

// Save your object
store.Save(completeProject);

// Send a message indicating its ready to be processed
bus.Send(new ProjectApproved() { ProjectId = completeProject.Id });

Windows服务在自己的时间内接收和处理消息

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Retrieve your object back
      var completeProject = store.Get(Message.ProjectId);
   }
}

为了使事情简单,我们使用:Rhino ESBTopshelf。配置非常简单,并且将其用于现有应用程序已证明只需很少的时间。


无论如何,使用带有CQRS的服务总线始终是提高可伸缩性的好方法
thinkbeforecoding 2010年

3

我很好奇为什么两者都不是一个可行的选择。现在,您触发了页面视图上的作业,其中一些不幸的树液被卡住,等待10秒钟才能显示页面。至少那是我对您当前方法的理解。

但是,随着网站的增长,这些工作的运行时间越来越长,并且您不想破坏网站上的用户体验。一天当中,甚至没有几个(或很多)不幸的用户,所以现在您正在考虑在后台调度作业。

我不明白为什么定期运行后台作业不能模仿访问者。现在我不是Windows程序员,但是在Linux世界中,我将设置一个cron作业,该作业以固定的间隔运行,并且它将有两行代码。

#!/bin/bash
wget -O /dev/null http://stackoverflow.com/specially_crafted_url

它结合了两个系统的优点。它是在后台完成的。它不会影响用户。它仍然使用页面视图开始工作。我以前见过这种方法。它往往是古老的简单方法和未来复杂方法之间的中间地带。

更新资料

我认为您可以通过在Web服务器本身上运行作业运行程序来解决负载平衡问题。作业运行程序将URL从作业队列中拉出,并按如下方式运行它:

wget -O /dev/null http://localhost/specially_crafted_url

由于作业/消息队列的性质,作业将在作业运行者之间平均分配,这意味着special_crafted_url最终将在您的Web服务器之间分配。


对于已经以可预测的间隔运行的所有事情,我们已经做到了,剩下的就是无法提前预测的事情。例如,仅在最近查看过的问题上更新“相关问题块”。标记的问题列表同样仅在有人关心检查这些标记时才被缓存。由于我们有超过一百万的问题,并且接近25,000个标签,因此“以防万一”,我们无法运行所有关联的任务(仅两个示例)。
凯文·蒙特罗斯

由于SO分散在多个服务器上,因此还存在负载平衡问题。基本上,如果您转到stackoverflow.com,您将始终访问同一台服务器。wget方法将迫使我们将所有任务编组到单个服务器上(或者实际上是重新设计我们的负载平衡设置),这确实很痛苦。
凯文·蒙特罗斯

如果事情按固定的时间间隔运行,那会很好,对吧?我确实理解您的意思,但是上面概述的方法(我认为还有其他一些人提到)没有改变。当页面浏览量显示“该运行该作业了”时,您将该作业停留在消息队列中。长时间运行的后台作业将运行找到的作业。在这种情况下,作业仅是需要请求的URL。嘿,您可能可以在每月20美元的共享服务器上进行设置,因为它不需要您的代码库即可运行。看一下Amazon SQS,它提供了易于使用的消息传递服务。
mellowsoon

关于负载平衡问题。只要有强大的意志,必有一条路为你开!您可以使用服务器的IP地址随机访问服务器,而不是向stackoverflow.com发出请求。如果负载均衡器检查cookie以传递请求,则可以伪造cookie。如果它检查IP地址,您甚至可能会伪造该地址(因为您不关心服务器的响应)。
mellowsoon

同意负载平衡不应成为这样做的理由。由于请求specially_crafted_url来自一个已知IP,因此您可以在负载均衡器上添加一条规则,仅对来自该IP的请求进行轮询。
波特曼2010年

2

我认为纯服务方法的缺点是,您会将代码分散到服务中,并且远离核心应用程序。

这是我们对大型后台非时间敏感型作业所做的工作,这些作业将代码保持在一起并简化了服务:

  1. 创建一个作业队列(内存中或数据库中,无论作业类型需要什么持久性)
  2. 创建一个将执行排队作业的Web服务
  3. 死定的简单服务应用程序,它以指定的时间间隔调用Web服务,而将所有复杂的内容(作业检索和执行)留给核心代码库中的Web服务。

甚至更简单,只需在控制台应用程序中进行调用,然后使用Task Scheduler或VisualCron将其转换为“服务”即可。


1
我在一个正在运行的重要应用程序中拥有了这个功能-Windows Service会定期触发Web应用程序。Web应用程序保持无状态,并根据需要从数据库中提取状态。工作请客。
贝文

1

我喜欢TopShelf。保持简单性,但仍以Windows服务运行的正确方式进行操作。基本上创建一个控制台应用程序,添加大约15-20行代码,然后将其作为服务安装。

http://code.google.com/p/topshelf/


1

如何在网络服务器上运行一个非常简单的Windows服务并定期命中一个执行其他任务的维护URL,该怎么办。让它限制在任何给定请求中执行多少工作。


1

我将在这里推翻明显的趋势,并建议使用IIS中的模型。我自己用过,效果很好。实现一个体面的线程池类真的不是那么难(多年来,我扩展了我的线程池类,以支持动态创建和销毁线程,重试作业等)。优点是:

  • 无需外部服务监控
  • 实施简单:无需跨进程编组,无需高级作业监控
  • 您仍处于IIS进程中,因此可以执行所有常规日志记录,依此类推(无需多个日志文件)
  • 大大简化了部署(更新服务时,您必须停止服务,复制文件,启动服务-这是对网站代码的常规更新之外的附加功能)

我认为,IIS内部解决方案只是将工作附加到随机页面视图上的“下一步”。


1

Resque很好。如果需要在完成后将结果通知您,甚至是Kthxbye

都基于Redis / Ruby。

老实说,如果您正在执行基于服务的方法,那么实际上并不需要将其与您当前的平台进行超级集成,我认为这是一个加分。我希望它可以是一个设置后遗忘的系统,可以运行(带有某种监视)并完成工作。我不知道它是否必须在同一平台上运行,因为它只是更新/修改数据库信息。

可以肯定的是,如果将这种工作移植到一个单独的实体中,那么您可以花更少的钱得到更多的收益,尤其是因为看来您正在处理线程问题。既ResqueKthxbye移动加工出来到单独的进程,以允许OS处理的并发性。

恢复

Kthxbye


我必须尝试Kthxbye,如果仅仅是因为它的名字!
内森·帕尔默

非常棒。接下来是ORLY?图书馆。可能是某种统计监视...;)
卢卡斯(Lukas

0

我将使用WAS托管的WCF服务来侦听MSMQ队列。

专业的

  • 激发并忘记来自Web应用的消息

  • MSMQ / WCF限制并重试

  • 保证交货; D

  • 死信管理

  • 分布式处理

  • WAS / MSMQ激活

骗子

  • MSMQ(还没有死……)

WCF中的MSMQ功能使使用MSMQ变得非常不错。是的,您将流血于配置,但好处将超过牺牲。


0

开发Web应用程序时,我遇到过几次。我们已经通过创建一个执行任务的Windows控制台应用程序,并创建了一个调度的任务来解决该问题,该任务经常运行以实际执行任务。


0

您可以使用Rx和类似以下内容将工作分流到一个(或多个)后台线程上:

var scheduler = new EventLoopScheduler( SchedulerThreadName );
_workToDo = new Subject<Action>();
var queueSubscription = _workToDo.ObserveOn( scheduler ).Subscribe( work => work() );
_cleanup = new CompositeDisposable( queueSubscription, scheduler );

使用方法:

var work = () => { ... };
_workToDo.OnNext( work ); // Can also put on error / on complete in here

将所有这些托管在一个只有一个类的类中(也称为单例,但请正确执行-使用IoC容器确定生活方式)。

您可以通过编写自定义调度程序来代替使用EventLoopScheduler(运行单个线程)来控制线程池的大小。


0

我已经实施过几次这种事情。在Windows上,我设置了一个Python命令行程序,该程序在不同时间执行某些操作。该程序还在端口上公开了xmlrpc接口。然后,计划任务作业每分钟运行一次并查询xmlrpc接口。如果它们没有启动,它将尝试启动它们。如果不能,它将通过电子邮件发送给我。

优点是运行的作业不受cron或计划的约束。我有一个流程作业,它每秒钟运行一次,但是在开始新作业之间会等待的时间越来越长,具体取决于它是否有工作要做。而且,它可以用于根据结果进行智能操作。遇到500错误?真的有很长的延迟吗?做其他事情。通知其他服务。等等。

相同的系统可以在UNIX上运行,但需要进行少量修改。


0

我自己没有答案,但问题出了声-我记得有些人在播客上一次讨论过它

Spolsky:我注意到您在博客上提出的一个问题是,您应该如何一般地处理重复维护任务?

阿特伍德:是的。

Spolsky:这是一个公平的描述吗?每个网站都有一些您不想在加载网页时执行的任务,但是您希望以某种重复的方式执行。

阿特伍德:是的,后台任务有点类似。

Spolsky:是的,那么您发现了什么?

阿特伍德(Atwood):恩,我最初在Twitter上问过,因为我只想要一些重量轻的东西。我真的不想写Windows服务。我觉得那是带外代码。加上实际上完成工作的代码实际上是一个网页,因为对我来说,网站上的逻辑工作单元是一个网页。因此,确实就像我们正在回拨该网站一样,就像该网站中的另一个请求一样,所以我认为它应该保持内联,并且我们在Twitter上向我推荐了这种小方法本质上是要以固定的到期时间将某些内容添加到应用程序缓存中,然后您要进行回调,以便在到期时调用某个起作用的函数,然后以相同的到期时间将其添加回缓存中。


1
是的,这种方法适用于比StackOverflow小得多的站点。不幸的是(或幸运的是,取决于您如何看待),规模是这里的大问题。
凯文·蒙特罗斯

@Kevin Montrose,我在这里恳求对域名的完全无知。您能否解释一下,为什么有一个秘密的网页(可能以较小的单位)执行工作,并由刷新页面/ cron作业调用,而其他地方却无法扩展?我毫不怀疑您是对的,但我很想学习。
2010年

您的特定建议(缓存过期)不会扩展,因为所有缓存过期(在ASP.NET中)都运行一个线程(这对较小的站点是一个聪明的技巧,就像以前那样)。一个cron任务不会扩展,因为我们已经超越单个服务器(SO现在是3,并且还在不断增加)和任何的cron任务将是创下了单台服务器(至少,改变这种不变的将是真正与我们的负载痛苦余额设置)。Cron任务还必须非常频繁地运行,因为这些任务的重复时间大约为几分钟。
凯文·蒙特罗斯

值得注意的是,我们确实使用“ cron样式”计划来减少运行频率,固定间隔,已经存在的任务,徽章授予和每日电子邮件通知之类的事情。
凯文·蒙特罗斯

0

Task Queue Java API概述

任务概念
在App Engine后台处理中,任务是对一小部分工作单元的完整描述。此描述包括两个部分:

  • 参数化任务的数据有效负载。
  • 实现任务的代码。

脱机Web挂钩的任务
幸运的是,Internet已经以HTTP请求及其响应的形式提供了这样的解决方案。数据有效载荷是HTTP请求的内容,例如Web表单变量,XML,JSON或编码的二进制数据。代码参考是URL本身。实际代码是服务器在准备响应时执行的逻辑。


我不建议使用GAE任务队列api,而是遵循其模型。他们考虑了一段时间,并编写了一个实现。
antony.trupe

0

两者都做

在问题路径中添加一个可选参数,以完成您当前根据用户请求进行的工作:

在大型站点上服务后台任务

创建一个在每台服务器上运行的控制台应用程序,并打开IIS日志共享二进制文件并将其读取到文件的当前末尾。当IIS刷新日志时,请使用filesystemwatcher或定时间隔向前读取以收集更新。

使用此信息来确定当前查看过哪些页面。

使用已解析日志中的页面URL来通过Webclient对象在localhost上调用URL的“额外版本”。

添加一些代码以在每个日志周期结束时切换文件,或在每个日志周期重新启动该过程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.