我有一个应用程序,每次请求页面时都会对数据库执行写操作。此db写入不是时间关键,因此出于性能原因,我使用MSMQ对页面进行排队。当然,我必须有一些东西来读取队列和处理请求,所以我写了一个类似于这个的类:
public class QueueProcessor {
public void Start()
{
// Create background thread to run ProcessInternal()
}
public void Stop()
{
// Stop the previously created thread
}
public void ProcessInternal()
{
while (runnable)
{
// check queue for messages, process them one at a time,
// then wait indefinitely for more messages
}
}
}
现在,由于这个网站本质上相当小,我真的不想在部署例程中添加Windows服务,所以我现在正在做的是在Application_Start中创建一个新的QueueProcessor事件并在那里开始。我的想法是线程将在应用程序的生命周期内运行,如果应用程序被IIS杀死,它将在下次有人访问页面时再次启动。
为了防止由于应用程序被IIS杀死而未处理排队消息的长时间闲置,我设置了一个wget请求,每隔几分钟就在一个站点的页面上执行,从而使应用程序保持活动状态确保后台线程继续运行。
我的问题是,我不经常看到这个设计,我想知道它是否有任何潜在的问题?
编辑:
在对这个主题进行一些阅读之后,我发现这种方法的主要问题(以及类似的方法,例如缓存删除回调函数)是他们被要求在可伸缩性方面执行的功能类型。例如,如果您正在进行大规模更新或其他事情,您显然不希望任务在所有Web服务器上运行 - 您将会有相互冲突的更新和潜在的数据丢失。
但是,在我的特殊情况下,该线程仅处理该服务器收到的请求,这些请求位于该服务器的消息队列中。因此,如果我将此应用程序扩展为5个服务器,则每个线程将处理每个服务器的排队消息而没有任何问题。同样,数据库中记录的顺序并不是那么重要,以至于在一个小间隔内来自不同服务器的一些类似请求会成为问题,所以我仍然认为这个解决方案对我的问题是合理的。
答案 0 :(得分:1)
我认为设置wget请求并不比部署Windows服务容易得多。 除此之外,我没有看到任何具体问题。如果可靠性和准确的时间并不重要,那么这将起作用。
答案 1 :(得分:1)
我在一些网站上使用了类似的方案,我毫不费力地保留了这些方案。要注意的主要事项是确保正确捕获线程中的所有异常。您不想拥有的是在您不知情的情况下死亡的线程,然后在应用程序回收时再次静默重启。
答案 2 :(得分:1)
虽然我不认为这是一个好主意,但杰夫和公司seem to use similar hackery要避免在这个网站上使用Windows服务(而Joel也为FogBugz做了)。由于规模和性能在这里得到了很好的证明 - 它看起来确实合理且可行。