处理长时间运行的报告

9
我正在处理一个使用C#编写的ASP.net应用程序,其数据库为Sql Server 2000。我们有几个PDF报告供客户使用,但问题在于这些报告需要一段时间才能生成(超过3分钟)。通常情况下,当用户请求报告时,请求超时会在Web服务器完成生成报告之前终止请求,因此用户永远没有机会下载文件。然后用户会刷新页面并重试,这会重新启动整个报告生成过程,并最终超时。(不,我们现在没有缓存报告;这是我正在努力推动的事情...)。
你如何处理这些情况?我脑海中有一个想法,涉及异步请求以开始报告生成,然后使用一些JavaScript定期检查状态。一旦状态表明报告已完成,则单独请求实际文件。
还有其他更简单的方法吗?
6个回答

5

这里建议使用文件系统。发送请求时,立即返回报告pdf位置的url。您的服务器可以启动一个外部进程或向自身发送请求以执行报告生成。客户端可以使用http HEAD轮询提供的url以获取PDF。如果将PDF文件名派生自报告参数(使用哈希或直接将参数放入名称中),则还可以实现即时服务器端缓存。


你能详细解释一下客户端如何使用HTTP HEAD来轮询服务器吗?我喜欢轮询的想法,但是我打算使用JavaScript来进行轮询。有没有更简单的方法? - Steven Williams
你可以从javascript发送头请求,http://www.jibbering.com/2002/4/httprequest.html可能有一些在jquery/其他大型js库中的东西可以帮助。 - user7375

4

我认为从处理的角度考虑,可以将这份报告更离线一些。

比如可以创建一个队列来存放报告请求,从队列中处理报告。完成后,可以向用户发送消息。

可能我甚至会为队列处理创建单独的Windows服务。

更新: 发送给用户可以是电子邮件或者他们可以有一个“报告”页面,在那里他们可以检查报告的状态并在报告就绪时下载它们。


2

将报告发送给用户怎么样?所有的asp页面只需要发送生成报告的请求并返回一条消息,表示报告将在运行完成后通过电子邮件发送。


那是我的第一反应,但我们系统的用户不需要拥有电子邮件地址。否则,这是个好建议。 - Steven Williams

2

您的用户可能不接受这种方法,但是:

当他们请求报告(通过点击按钮或链接等)时,您可以在单独的线程上启动报告生成过程,并将用户重定向到一个页面,显示“谢谢,您的报告将在几分钟内通过电子邮件发送给您。”

当线程完成报告生成时,您可以直接发送PDF文件(由于文件大小可能无法实现),或者将报告保存在服务器上并向用户发送链接。

或者,您可以进入IIS并将超时时间提高到大于3分钟。


2
以下是如果我遇到这个问题时会采取的一些措施:
1- 停止那些超时!它们是资源的彻底浪费。(将asp页面的超时值提高)
2- 将所有数据库访问集中在一个单一点上,然后收集关于由谁何时运行了哪些报告以及花费了多少时间的统计数据。调查为什么需要这么长时间,是因为报告复杂性?数据范围?服务器负载?(您实际上可以将其全部写在服务器上的 .csv 文件中,并定期导入此文件以供稍后分析)。
最终,如果您通过这个单一访问点进行“缓存”报告,那么您将更容易地进行操作(例如,相同查询相同日期将返回先前生成的相同PDF)
3- 我知道这真的不是问题,但您是否尝试过深入了解这些查询为什么要运行这么长时间?查询优化可能吗?
4- 当报告准备就绪时,电子邮件/短信/屏幕消息似乎很棒...如果您的用户通常发送一批要生成的报告,则可以在应用程序中构建显示“其”队列进度的小型仪表板。一个小的ajax控件将定期刷新状态。 提示:如果您使用了该中央数据库访问并且拥有关于运行何时,为什么以及多长时间的足够信息,则最终将能够粗略地估计报告运行所需的时间。
如果响应时间至关重要,某些用户在一天中的某些时间段内是否应限制数据范围(例如日期范围)?
祝您好运,请在需要更准确的提示时发布有关您情况的更多详细信息...

2
查询调优可能是您开始的最佳位置。虽然我不知道您正在生成报告,但这一步骤实际上不应该花费太长时间。另一方面,性能较差的查询可能会严重影响性能。
根据您在查询中发现的内容,您可能需要添加一些索引,或者甚至设置一个表以非规范化的方式存储报告信息,以使其更快地可用。可以通过 SQL Server 作业每小时或根据您的要求(在合理范围内)刷新此非规范化表。
如果它是一个相对静态的报告,没有变化的用户输入参数,则缓存当天早些时候运行的报告也是一个好主意,但是如果不了解您的情况,很难再说更多。
对于这样的问题,除非您有理由怀疑您的报告生成代码是罪魁祸首,否则您确实需要从数据库开始。您可以使用各种临时解决方案一段时间,但如果您的数据库是根本原因,那么这些解决方案将无法很好地扩展,并且您可能会在未来遇到类似问题(或更糟的问题)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接