Asp.net mvc 重载asp.net MVC+;webapi应用与异步消息总线

Asp.net mvc 重载asp.net MVC+;webapi应用与异步消息总线,asp.net-mvc,asynchronous,asp.net-web-api,signalr,message-bus,Asp.net Mvc,Asynchronous,Asp.net Web Api,Signalr,Message Bus,我计划构建一个相当大的应用程序(在并发用户/请求数量方面,而不是在功能方面) 基本上,我在某处会有一个服务,它在等待命令执行它们,然后确认完成。该服务将使用服务总线进行通信,从而在发出确认消息之前最终执行 此服务的使用者可以是任何类型的应用程序(WPF、SL等),但我的主(也是第一个)客户端将是asp.net MVC应用程序+WebApi(.net 4.5)或仅MVC(.net 4.0),并带有ajax控制器操作 web应用程序将依赖Ajax调用来保持用户友好的响应应用程序 我对这种成熟的异步体

我计划构建一个相当大的应用程序(在并发用户/请求数量方面,而不是在功能方面)

基本上,我在某处会有一个服务,它在等待命令执行它们,然后确认完成。该服务将使用服务总线进行通信,从而在发出确认消息之前最终执行

此服务的使用者可以是任何类型的应用程序(WPF、SL等),但我的主(也是第一个)客户端将是asp.net MVC应用程序+WebApi(.net 4.5)或仅MVC(.net 4.0),并带有ajax控制器操作

web应用程序将依赖Ajax调用来保持用户友好的响应应用程序

我对这种成熟的异步体系结构非常陌生,我有一些问题要问,以避免将来的头痛:

  • 我的web api调用可能需要一些时间。我应该如何正确设计api以支持长时间运行的操作(某种异步?)。我已经读过有关新的async关键字的内容,但为了了解更多信息,我想了解其背后的含义
  • 我对服务的调用将包括发布消息并等待ack消息。如果我把它包装在一个方法中,我应该如何编写这个方法?我是否应该“阻止”直到收到ack(我想我不应该)?我是否应该返回一个任务对象并让使用者决定
  • 我还想知道信号员是否能帮我。有了signar,我想我可以使用一个真正的“fire-and-forget”命令发出,并将消息路由到客户端以确认消息
  • 我是否完全脱离了主题,我是否应该采取另一种方法
在实施细节/框架方面,我认为我将使用:

  • Rabbitmq as消息传递系统
  • Masstransit对消息传递系统进行抽象
  • asp.MVC4来构建UI
  • Webapi隔离从UI控制器发出的命令,并允许其他类型的客户端发出命令
我的web api调用可能需要一些时间。我应该如何设计 正确使用api以支持长时间运行的操作(某种 异步?)。我已经读过关于新的async关键字的内容,但是为了 知识,我想了解背后的原因

关于Async,我在stackoverflow的另一个问题上看到了这个链接:

它表示,当向ASP.NET应用程序发出请求时,将分配一个线程来处理来自有限线程池的请求

异步控制器操作将线程释放回线程池,以便它准备好接受附加请求。在操作中,需要异步执行的操作被分配给回调控制器操作

异步控制器操作使用Async作为后缀命名,回调操作具有完整的后缀

public void NewsAsync(string city) {}
public ActionResult NewsCompleted(string[] headlines) {}
关于何时使用异步:

通常,在以下情况下使用异步管道 是真的:

  • 这些操作是网络绑定或I/O绑定的,而不是CPU绑定的
  • 测试表明,阻塞操作是站点性能的瓶颈,IIS可以使用
    这些阻塞调用的异步操作方法
  • 并行性比代码的简单性更重要
  • 您希望提供一种机制,允许用户取消长时间运行的请求
我认为使用ASP.NETMVC和WebAPI开发您的服务,并在需要时使用异步控制器,这将是开发高可用性Web服务的好方法

使用基于消息的服务框架(如ServiceStack)看起来也不错:

额外资源:

//还显示了性能测试的设置

我的web api调用可能需要一些时间。 我应该如何正确设计api以支持长 运行操作(某种异步?)

我不是100%确定你要去哪里。通过引入RabbitMQ和MassTransit,您可以询问有关异步的问题,但也可以提到消息队列。默认情况下,消息队列是异步的

您还提到执行命令。如果您指的是CQR,那么可以将命令和查询分开。但我不是百分之百地谈论的是您在提到“长时间运行的流程”时所指的内容

  • 查询数据时,数据应该已经存在。最好是以手头问题所需的方式
  • 查询数据时,不应启动长时间运行的进程
  • 执行命令时,可以启动长时间运行的进程。但这就是为什么您应该使用消息队列。指定一个任务来启动长时间运行的进程,为其创建消息,将其抛出队列,完全忘掉它。后台的其他进程将接收它
  • 当执行该命令时,可以启动长时间运行的进程
  • 执行命令时,可以使用数据更新数据库
  • 如果有人请求数据,API可以使用这些数据
使用此模型时,长时间运行的过程可能需要10分钟才能完成并不重要。我不会详细介绍实际上一个线程需要10分钟才能完成,包括数据库上的锁,但我希望您能理解这一点。在将消息抛出队列后,您的API几乎立即可用。那里不需要异步

我对服务的调用将包括发布消息并等待ack消息

我不明白。NET Framework和您的排队平台将为您解决这一问题。你为什么要等一个ack

集体运输

Bus.Instance.Publish(new YourMessage{Text = "Hi"});
在NServiceBus中

Bus.Publish(new YourMessage{Text = "Hi"});
我还想知道信号员是否能帮我

我想是的!由于消息传递的异步性质,用户必须“等待”