处理长期运行的报告

我正在使用C#编写的带有Sql Server 2000数据库的ASP.net应用程序。 我们有几份PDF报告,客户可以根据业务需求使用这些报告。 问题是这些报告需要一段时间才能生成(> 3分钟)。 通常最终发生的事情是当用户请求报告时,请求超时在Web服务器有时间完成生成报告之前终止请求,因此用户永远不会有机会下载文件。 然后,用户将刷新页面并再次尝试,这将启动整个报告生成过程,并且仍然会结束超时。 (不,我们现在没有缓存报告;这是我努力推动的事情……)。

你如何处理这些情况? 我脑子里有一个想法,包括提出一个启动报告生成的同步请求,然后有一些javascript来定期检查状态。 状态指示报告完成后,再单独请求实际文件。

有没有一种我没有看到的更简单的方法?

在这里使用文件系统可能是一个不错的选择。 请求立即将URL返回到报告pdf位置。 然后,您的服务器可以启动外部进程或向自己发送请求以执行报告。 客户端可以在提供的URL上轮询服务器(使用http HEAD)以获取PDF。 如果您使PDF的文件名从报表参数派生,可以使用哈希或直接将参数放入名称中,您也可以获得即时服务器端缓存。

从处理的角度来看,我会考虑使这个报告在某种程度上更加离线。

就像创建一个队列来放入报告请求一样,从那里处理报告,完成后,它可以向用户发送一条消息。

也许我甚至会为队列处理创建一个单独的Windows服务。

更新:发送给用户可以是电子邮件,也可以有“报告”页面,他们可以检查报告的状态并在准备好后下载。

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

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

完成生成报告的线程后,您可以直接通过电子邮件发送PDF(由于大小可能无法正常工作),或者将报告保存在服务器上并通过电子邮件发送给用户的链接。

或者,您可以进入IIS并将超时提升到> 3分钟。

如果我遇到这个问题,以下是我会做的一些事情:

1-停止那些超时! 他们完全浪费资源。 (调出asp页面的超时值)

2-在一个点中集中所有数据库访问,然后收集有关由谁执行的报告以及花费的时间的统计信息。 调查为什么需要这么长时间,是因为报告的复杂性? 数据范围? 服务器负载? (您实际上可以在服务器上的.csv文件中写入该文件,并在sql server中定期导入此文件以便稍后进行分析)。

最终,如果您通过此单一访问点,您将更容易“缓存”报告(例如,相同查询相同日期将返回先前生成的相同PDF)

3-我知道这不是问题,但你是否试过深入研究这些问题,看看它们为什么这么长时间运行? 查询调优可能吗?

4-报告准备就绪时的电子邮件/短信/屏幕消息似乎很好……如果您的用户通常发送一批要生成的报告,可能会在应用程序中构建一个指示“他们的”队列进度的小仪表板。 一个小的ajax控件会定期刷新状态。提示:如果你使用了这个中央数据库访问,并且你有足够的信息来了解为什么以及如何运行什么,你最终将能够粗略估计报告所需的时间跑步。

如果响应时间是关键任务,那么某些用户是否应该在一天中的某些时段限制数据范围(例如日期范围)?

祝您好运,如果您想获得更准确的提示,请发布有关您的方案的更多详细信息……

查询调优可能是您最好的起点。 虽然我不知道你正在生成报告,但这一步不应该那么久。 另一方面,性能不佳的查询可能会严重影响您的性能。

根据您在查看查询时发现的内容,您可能需要添加一些索引,甚至可能需要设置一个表以非规范化方式存储报表的信息,以使其更快地可用。 然后可以每小时刷新这个非规范化表(通过SQL Server作业),或者以您的要求(在合理范围内)的任何频率刷新。

如果它是一个相对静态的报告,没有不同的用户输入参数,那么缓存当天早些时候运行的报告也是一个好主意,但它很难在不知道你的情况下再说这个。

对于这样的问题,你真的需要从数据库开始,除非你有理由怀疑你的报告生成代码是罪魁祸首。 您可以使用各种可能有助于一段时间的创可贴,但如果您的数据库是根本原因,那么这些解决方案将无法很好地扩展,并且您可能会在未来某个时间遇到类似问题(或更糟) 。

如何通过电子邮件将报告发送给用户。 所有asp页面都应该发送生成报告的请求,并返回一条消息,报告将在完成运行后通过电子邮件发送。