我们有一个ASP MVC 3.0应用程序,它使用Entity框架从数据库读取数据(全部在Azure上)。我们有几个长时间运行的查询(已完成优化),我们希望确保解决方案可扩展并防止线程不足。
我们查看了异步控制器并使用I / O完成端口来运行查询(使用BeginExecute而不是通常的EF)。但是,异步很难调试并增加了代码的复杂性。
建议的解决方案如下:
Web服务器(Web角色)获取涉及长时间运行查询的请求(示例客户细分)
它将请求信息与相关参数一起输入表中并返回,从而允许线程处理其他请求。
我们在数据库中设置了一个标志,使用户可以在每次刷新页面时声明查询正在进行中。
工作人员角色不断查询此表,一旦发现此条目处理长时间运行的查询(客户细分),并使用结果更新原始客户表。
在这种情况下,不需要立即向用户返回状态。用户可以在几分钟内回来查看他们的请求是否已被处理。而不是表我们计划使用Azure队列(但我想Azure队列不能通知工作者角色,所以db表会做得很好)。这是一个可行的解决方案吗?这样做有什么陷阱吗?
答案 0 :(得分:1)
虽然Windows Azure存储队列在处理完邮件后没有给出通知,但您可以自己实现(可能使用Windows Azure存储表)。关于队列的好处:它们处理并发和失败的尝试。
例如:如果有2个工作实例处理来自同一队列的消息,则每次读取队列消息时,消息将在队列中不可见,持续一段时间。虽然不可见,但只有读取消息的工作者实例才有它。如果该实例完成处理,它只能删除队列消息(并更新您的通知表)。如果失败(可能是由于角色实例崩溃),则在隐身超时到期后,该消息会重新出现在队列中。更进一步:让我们说它只是一个错误的消息,导致您的代码每次都崩溃。您可以在处理消息之前检查出队计数。如果它大于2,则只需将消息存储在死信表中并手动检查。
对队列的一个警告:队列消息需要幂等操作(也就是说,它们至少可以处理一次,结果每次都应该具有完全相同的副作用)。
如果你使用表而不是队列,则需要处理扩展(处理表的多个线程或角色实例)和死信处理。
答案 1 :(得分:1)
这取决于。如果您的工作者角色除了将繁重的工作委托给SQL数据库之外什么都不做,那么这似乎是浪费资源和资金。使用具有异步请求的Web角色可以降低成本。如果需要在工作者角色中做大量工作,那么这是一个很好的方法。
您还可以使用AJAX或Web套接字。启动数据库查询,并立即返回响应。客户端可以轮询Web角色以查看查询是否已完成(如果使用HTTP),或者Web角色可以直接通知客户端(如果使用Web套接字)。
最诚挚的问候,
徐明。