C# 长期运行的查询web应用程序(azure)解决方案
我们有一个ASP MVC 3.0应用程序,它使用实体框架(都在Azure上)从数据库读取数据。我们有几个长时间运行的查询(优化已经完成),我们希望确保解决方案是可伸缩的,并防止线程不足 我们研究了异步控制器和使用I/O完成端口来运行查询(使用BeginExecute而不是通常的EF)。然而,异步很难调试,并且增加了代码的复杂性 建议的解决办法如下:C# 长期运行的查询web应用程序(azure)解决方案,c#,.net,sql-server,asp.net-mvc-3,azure,C#,.net,Sql Server,Asp.net Mvc 3,Azure,我们有一个ASP MVC 3.0应用程序,它使用实体框架(都在Azure上)从数据库读取数据。我们有几个长时间运行的查询(优化已经完成),我们希望确保解决方案是可伸缩的,并防止线程不足 我们研究了异步控制器和使用I/O完成端口来运行查询(使用BeginExecute而不是通常的EF)。然而,异步很难调试,并且增加了代码的复杂性 建议的解决办法如下: web服务器(web角色)获取涉及长时间运行的查询的请求(例如客户细分) 它将请求信息与相关参数一起输入到表中并返回,从而允许线程处理其他请求 我们
在这种情况下,不需要立即向用户返回状态。用户可以在几分钟内再次查看他们的请求是否得到了处理。我们计划使用Azure队列而不是表(但我想Azure队列无法通知工作者角色,所以db表就可以了)。这是可行的解决办法吗。这样做有什么陷阱吗 虽然在处理邮件后,Windows Azure存储队列不会向您发送通知,但您可以自己实现(可能使用Windows Azure存储表)。队列的好处在于:它们处理并发性和失败的尝试 例如:如果有两个工作者实例处理来自同一队列的消息,则每次读取队列消息时,该消息在您指定的时间内在队列中不可见。虽然不可见,但只有读取消息的工作实例才具有该消息。如果该实例完成了处理,它可以删除队列消息(并更新通知表)。如果失败(可能是由于角色实例崩溃),消息将在不可见性超时过期后重新显示在队列上。更进一步:假设它只是一条错误消息,每次都会导致代码崩溃。您可以在处理消息之前检查出列计数。如果大于(比如)2,只需将消息存储在死信表中并手动检查即可 关于队列的一个警告:队列消息需要是幂等操作(也就是说,它们至少可以被处理一次,每次结果都应该有完全相同的副作用)
如果使用表而不是队列,则需要处理扩展(处理表的多线程或角色实例)和死信处理。这取决于具体情况。如果您的工作者角色除了将繁重的工作委托给SQL数据库之外什么都不做,那么这似乎是在浪费资源和金钱。通过将web角色与异步请求一起使用,可以降低成本。如果需要在工作者角色本身完成繁重的工作,那么这是一个很好的方法 您还可以使用AJAX或web套接字。启动数据库查询,并立即返回响应。客户端可以轮询web角色以查看查询是否已完成(如果使用HTTP),或者web角色可以直接通知客户端(如果使用web套接字) 致以最良好的祝愿
徐明。David-非常感谢您的澄清。我们将排队。但总的来说,这是我们计划采取的可行解决方案(而且是一个不被反对的方案:))-工人角色负责长时间运行的查询,而不是使web角色异步?明-工人角色需要进行一些繁重的处理,还需要与第三方web服务进行通信,发送电子邮件和短信等。只是好奇-当你说立即启动查询并返回响应时,我需要使用BeginExecute权限。我假设我不能使用EF。我的意思是:启动一个后台线程来处理数据库(它可以是同步的,也可以是异步的)。处理客户机请求的主方法立即返回响应。不要等到后台线程完成。