我正在开发一个用C#编写的带有Sql Server 2000数据库的ASP.net应用程序。我们有几份PDF报告,客户可以根据业务需求使用这些报告。问题是这些报告需要一段时间才能生成(> 3分钟)。通常最终发生的事情是当用户请求报告时,请求超时在Web服务器有时间完成生成报告之前终止请求,因此用户永远不会有机会下载文件。然后,用户将刷新页面并再次尝试,这将启动整个报告生成过程,并且仍然会结束超时。 (不,我们现在没有缓存报告;这是我正在努力争取的......)。
您如何处理这些情况?我脑子里有一个想法,包括提出一个启动报告生成的同步请求,然后有一些javascript来定期检查状态。状态指示报告完成后,再单独请求实际文件。
我没有看到更简单的方法吗?
答案 0 :(得分:5)
在这里使用文件系统可能是一个不错的选择。请求立即将URL返回到报告pdf位置。然后,您的服务器可以启动外部进程或向自己发送请求以执行报告。客户端可以在提供的URL上轮询服务器(使用http HEAD)以获取PDF。如果您使用报表参数来创建PDF的文件名,可以使用哈希或直接将参数放入名称中,也可以获得即时服务器端缓存。
答案 1 :(得分:4)
我会考虑从处理的角度来看这个报告有点离线。
比如创建一个队列来放入报告请求,从那里处理报告,完成后,它可以向用户发送消息。
也许我甚至会为队列处理创建一个单独的Windows服务。
更新:发送给用户可以是电子邮件,也可以有“报告”页面,他们可以检查报告的状态,并在准备好后下载。
答案 2 :(得分:2)
您的用户可能不接受此方法,但是:
当他们请求报告时(通过单击按钮或链接或其他内容),您可以在单独的线程上启动报告生成过程,并将用户重定向到“谢谢您,您的报告将会显示的页面”几分钟后通过电子邮件发送给你。“
线程完成生成报告后,您可以直接通过电子邮件发送PDF(由于大小可能无法正常工作),或者将报告保存在服务器上并通过电子邮件发送给用户的链接。
或者,您可以进入IIS并将超时提升到> 3分钟。
答案 3 :(得分:2)
如果我遇到这个问题,以下是我会做的一些事情:
1-停止超时!他们完全浪费资源。 (调出asp页面的超时值)
2-在一个点中集中所有数据库访问,然后收集有关哪些报告由谁执行以及花费了多少时间的统计信息。调查为什么需要这么长时间,是因为报告的复杂性?数据范围?服务器负载? (您实际上可以在服务器上的.csv文件中写入该文件,并在sql server中定期导入此文件以便稍后进行分析。)
最终,如果您通过此单一访问点,您将更容易“缓存”报告(例如,同一查询相同日期将返回之前生成的相同PDF)
3-我知道这不是问题,但你是否试过深入研究这些问题,看看为什么这么长时间才能运行?查询调优可能吗?
当报告准备就绪时,电子邮件/短信/屏幕消息显示很好......如果您的用户通常发送一批要生成的报告,可能会在应用程序中构建一个指示“他们的”队列进度的小仪表板。一个小的ajax控件会定期刷新状态.. 提示:如果您使用了中央数据库访问权限,并且您有足够的信息可以了解为什么以及如何长时间运行,那么您最终将能够粗略估计报告运行所需的时间。如果响应时间是关键任务,那么某些用户是否应该在一天中的某些时段限制数据范围(例如日期范围)?
祝您好运,如果您想获得更准确的提示,请发布有关您的方案的更多详细信息......
答案 4 :(得分:2)
查询调优可能是您最好的起点。虽然我不知道你正在生成报告,但这一步不应该那么久。另一方面,性能不佳的查询可能会严重影响您的性能。
根据您在查看查询时发现的内容,您可能需要添加一些索引,甚至可能需要设置一个表以非规范化方式存储报表的信息,以使其更快地可用。然后可以每小时刷新一次非规范化表(通过SQL Server作业),或者按照您的要求(在合理范围内)的任何频率刷新。
如果它是一个相对静态的报告,没有不同的用户输入参数,那么缓存当天早些时候运行的报告也是一个好主意,但它很难在不知道你的情况下再说这个。
对于这样的问题,你真的需要从数据库开始,除非你有理由怀疑你的报告生成代码是罪魁祸首。您可以使用各种可能有一段时间帮助的创可贴,但如果您的数据库是根本原因,那么这些解决方案将无法很好地扩展,并且您可能会在未来某个时间遇到类似的问题(或更糟)
答案 5 :(得分:1)
如何通过电子邮件将报告发送给用户。所有asp页面应该发送请求以生成报告,并返回一条消息,报告将在完成运行后通过电子邮件发送。