在asp.net-mvc中,在不影响其他用户的情况下进行昂贵操作的正确方法是什么?

leo*_*ora 18 asp.net-mvc performance reporting scalability

大约5年前,我问过这个问题,关于如何"卸载"用户不需要等待的昂贵操作(例如auditng等),这样他们就可以更快地得到前端的响应.

我现在有一个相关但不同的问题.在我的asp.net-mvc上,我构建了一些报告页面,您可以在其中生成Excel报告(我正在使用EPPlus)和powerpoint报告(我正在使用aspose.slides).这是一个示例控制器操作:

    public ActionResult GenerateExcelReport(FilterParams args)
    {
        byte[] results = GenerateLargeExcelReportThatTake30Seconds(args);
        return File(results, @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", "MyReport.xlsx");
    }
Run Code Online (Sandbox Code Playgroud)

该功能运行良好,但我试图弄清楚这些昂贵的操作(一些报告可能需要30秒才能返回)正在影响其他用户.在上一个问题中,我有一个昂贵的操作,用户DIDN"T必须等待,但在这种情况下,他必须等待它的同步活动(点击生成报告和期望是用户在完成后获得报告)

在这种情况下,我不在乎主要用户必须等待30秒,但我只是想确保我不会因为这种昂贵的操作,生成文件等而对其他用户产生负面影响.

这个用例在asp.net-mvc中是否有最佳实践?

Vin*_*nod 6

您可以尝试组合Hangfire和SignalR.使用Hangfire启动后台作业并放弃http请求.一旦报告生成完成,使用SignalR生成推送通知.

从服务器到客户端的SignalR通知

备用选项是在客户端实现轮询机制.发送ajax调用以获取hangfire作业以生成报告.然后使用另一个提供状态的ajax调用开始轮询一些api,并在报告准备就绪后立即检索它.我更喜欢使用SignalR而不是轮询.

如果报告处理正在影响Web服务器上的性能,请将该处理卸载到另一台服务器.您可以使用消息传递(ActiveMQ或RabbitMQ或您选择的其他框架)或rest api调用来启动另一台服务器上的报告生成,然后再次使用消息传递或rest api调用将报告生成完成通知回Web服务器,最后是SignalR通知客户.这将使Web服务器更具响应性.

更新 关于你的问题

这个用例是否在asp.net-mvc中有最佳实践

您必须加班监控您的申请.监控客户端和服务器端.您可以依赖的工具很少,例如newrelic,app dynamics.我使用了newrelic,它具有跟踪客户端浏览器和服务器端问题的功能.产品名称为"NewRelic Browser"和"NewRelic Server".我相信还有其他工具可以捕获类似的信息.

超时分析指标,如果发现任何异常,请采取适当的措施.如果您发现服务器端CPU和内存峰值,请尝试在相同时间范围内捕获客户端上的指标.在客户端,如果您发现任何超时问题,则连接错误意味着您的应用程序用户无法在服务器执行繁重操作时连接到您的应用程序.接下来尝试识别服务器端瓶颈.如果没有足够的空间来调整代码,那么请通过一些服务器容量规划练习,找出如何进一步扩展硬件或将后台作业移出Web服务器以减少负载.仅使用这些工具捕获指标可能还不够,您可能必须对应用程序进行检测(日志捕获)以捕获其他指标以正确监控应用程序运行状况.

在这里,您可以找到有关Microsoft的.net应用程序容量规划的一些信息.

-Vinod.


Rob*_*kal 5

这些都是关于如何将工作移出请求/响应周期的好主意.但我认为@leora只是想知道一个长期运行的请求是否会对asp.net应用程序的其他用户产生负面影响.

答案是不.asp.net是多线程的.每个请求都由一个单独的工作线程处理.