结合AngularJS / .NET Web API应用程序的RabbitMQ架构

luk*_*egf 2 c# rabbitmq reporting-services asp.net-web-api

因此,我有一个SPA(单页应用程序),其中AngularJS作为前端,.NET Web API作为后端(C#)。我需要根据某些用户操作来生成SQL Server Reporting Services(SSRS)报告,即选择一些数据并按一个按钮。这是我现有架构的粗略插图:

FRONT END                 BACK END                  SSRS Report
==========                =========                 ===========
**AngularJS Web page**-->**.NET Web API controller**-->**Intermediary class (passes arguments to report)** -->**Generate report and save to file**
Run Code Online (Sandbox Code Playgroud)

这行得通,但问题是在生成报告时,应用程序必须坐在那里等待它们完成,同时用户无法执行任何操作。如果要创建许多报告(例如100多个),则可能要花一两分钟以上的时间,这对我来说是不可接受的。

因此,这就是RabbitMQ的用处。我的想法是让.NET Web API控制器将消息发送到服务器,一旦服务器接收到消息,就会对上面的中间类进行调用,从而生成报告,然后响应发送回客户端,让他们知道已生成报告。我认为我需要为此使用RPC方案,因此我已经在RabbitMQ网站上完成了相应的教程,而且看起来很简单。

我不知道的是,这是我的问题,是如何从.NET Web API应用程序启动客户端和服务器。坦白说,我现在有点迷茫,因为这是我第一次体验任何消息,并且在架构方面我不确定如何处理它。如果我能详细了解整个工作原理,则可以从那里进行编码,但是到现在为止,我很难想象如何构造应用程序。

所以,问题:

  1. 如何从.NET Web API控制器启动RabbitMQ服务器和客户端?服务器和客户端应该是类库还是控制台应用程序,还是完全其他?

  2. 我正在构想的体系结构可以工作还是有更好的方法?

  3. 任何有关如何实现我要达到的目标的一般建议将不胜感激。

Evk*_*Evk 5

  1. RabbitMQ服务器不是您从控制器启动的东西-它始终在运行。您可以从控制器向Rabbitmq服务器发送消息。另一方面,另一个应用程序(Windows服务,控制台应用程序,甚至Linux上的mono服务)侦听并处理这些消息。RabbitMQ服务器仅管理端点之间的消息发送。在您的情况下,处理来自控制器的消息的应用程序也始终在运行(将其设置为Windows服务是合理的)。

  2. 这样的体系结构是可以的。RabbitMQ可能是一个过大的杀伤力-对于多服务器,高负载的情况更是如此。如果您的负载较低,并且所有应用程序都在同一台服务器上,则可以使用其他工具(例如hangfire.io,MSMQ,甚至可以在Web服务器进程中运行后台任务,如另一个答案所示)。如果简单的工具可以胜任您的工作-为什么不呢?

  3. 生成报告时,不要一直保持从客户端(浏览器)到服务器的连接。只需将任务放在Rabbit队列中进行处理(否则将开始生成报告)并返回。然后,如果作业完成,则定期从客户端轮询,或者(更好)通过websocket连接通知客户端。如果生成报告可能要花费一些时间(比如说超过30秒),则当然是这样。

更新:有关整体体系结构的更多信息。

  • RabbitMQ服务器作为Windows服务运行,与Windows一起启动。
  • 当您通过Web API收到生成报告的请求时,您将GenerateReport消息与所有必需信息放在一起,然后返回(不等待生成报告)。如果您将报告存储在数据库中,那么它们是持久的-在数据库中创建有关报告请求的记录。否则-将有关待处理报告的信息保留在内存中(以便您知道当前正在生成X个报告)。在理想情况下,您还可以通过Web套接字在客户端和服务器之间建立持久连接。如果是这样,您将实时通知用户报告生成状态。否则-用户将不得不不时轮询服务器。
  • 另一方面,您编写了Windows服务,它也与Windows服务器一起启动。它侦听GenerateReport消息并开始生成。可以有多个这样的服务,或者您可以在一个服务中拥有多个订阅-这将在多个服务之间平均分配工作量。在报告生成期间-发布ReportProgress消息。完成后-更新数据库中的报告(如果您将其持久化)并发布ReportDone消息。Web Api服务中的后台线程侦听此类消息。如果您具有websockets连接-您只需将这些消息传递给客户端,这样他就可以实时查看报告生成进度。否则-更新数据库或内存结构,以便下次客户下次轮询报告状态时-您有返回的内容。
  • 如果出现问题-没问题(如果您将报告持久保存在数据库中)。在启动时,您的生成服务将检入数据库中是否有待处理的报告并生成它们。如果客户端在报告生成过程中(从网站)断开连接-仍然没有问题,则当他返回报告时就可以使用数据库了。如果Web API服务崩溃-仍然没有问题。