5

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

基本上,我会在某处提供服务,即等待命令执行它们,并在稍后确认完成。在发出确认消息之前,该服务将使用服务总线进行通信,最终执行。

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

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

我对这种成熟的异步架构很陌生,我有一些问题可以避免未来的头痛:

  • 我的 web api 调用可能需要一些时间。我应该如何正确设计 api 以支持长时间运行的操作(某种异步?)。我已经阅读了新的 async 关键字,但为了知识,我想了解其背后的内容。
  • 我对服务的调用将包括发布消息并等待确认消息。如果我将它包装在一个方法中,我应该如何编写这个方法?我应该“阻止”直到收到确认(我想我不应该)?我应该返回一个 Task 对象并让消费者决定吗?
  • 我也想知道 SignalR 是否可以帮助我。使用 signalR,我想我可以使用真正的“即发即弃”命令发出,并路由到客户端以确认消息。
  • 我是否完全脱离主题,我应该采取另一种方法吗?

在实现细节/框架方面,我想我会使用:

  • Rabbitmq 作为消息系统
  • Masstransit 抽象消息系统
  • asp.MVC 4 构建 UI
  • Webapi 隔离从 UI 控制器发出的命令,并允许其他类型的客户端发出命令
4

2 回答 2

2

我的 web api 调用可能需要一些时间。我应该如何正确设计 api 以支持长时间运行的操作(某种异步?)。我已经阅读了新的 async 关键字,但为了知识,我想了解其背后的内容。

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

http://msdn.microsoft.com/en-us/library/ee728598(v=vs.100).aspx

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

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

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

public void NewsAsync(string city) {}
public ActionResult NewsCompleted(string[] headlines) {}

关于何时使用异步:

通常,当满足以下条件时,使用异步管道:

  • 这些操作是网络绑定或 I/O 绑定的,而不是 CPU 绑定的。
  • 测试表明阻塞操作是站点性能的瓶颈,并且 IIS 可以通过
    对这些阻塞调用使用异步操作方法来服务更多请求。
  • 并行性比代码的简单性更重要。
  • 您希望提供一种机制,让用户取消长时间运行的请求。

我认为使用带有 Web API 的 ASP .NET MVC 开发您的服务并在需要时使用异步控制器将是开发高可用性 Web 服务的好方法。

使用像 ServiceStack 这样的基于消息的服务框架看起来也不错:

http://www.servicestack.net/

其他资源:

http://msdn.microsoft.com/en-us/magazine/cc163725.aspx http://www.codethinked.com/net-40-and-systemthreadingtasks http://dotnet.dzone.com/news/net-区域进化 http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx http://channel9.msdn.com/Events/TechDays/Techdays-2012-the-荷兰/2287 http://www.dotnetcurry.com/ShowArticle.aspx?ID=948 // 还显示了性能测试的设置 http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-方法-in-aspnet-mvc-4 http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx http://hanselminutes.com/327/everything-网络程序员知道异步编程是错误的 http://www.hanselman.com/blog/TheMagicOfUsingAsynchronousMethodsInASPNET45PlusAnImportantGotcha.aspx

于 2013-11-24T09:18:27.210 回答
2

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

我不是 100% 确定你要去哪里。你问了关于异步的问题,但也提到了消息队列,包括 RabbitMQ 和 MassTransit。消息队列默认是异步的。

您还提到执行命令。如果您指的是 CQRS,则将命令和查询分开。但是我不是 100% 提到的是你在提到“长时间运行的进程”时所指的内容。

  • 当您查询数据时,数据应该已经存在。最好以手头问题所需的方式。
  • 查询数据时,不应启动长时间运行的进程
  • 当您执行命令时,可以启动一个长时间运行的进程。但这就是您应该使用消息队列的原因。指定一个任务来启动长时间运行的进程,为它创建一条消息,把它扔到队列中,完全忘记它。后台的其他一些进程将接收它。
  • 执行命令后,可以启动长时间运行的进程。
  • 执行命令时,可以使用数据更新数据库
  • 如果有人请求数据,API 可以使用此数据

使用此模型时,长时间运行的过程可能需要长达 10 分钟才能完成并不重要。我不会详细说明实际上有一个线程最多需要 10 分钟才能完成,包括数据库锁定,但我希望你明白这一点。将消息扔到队列后,您的 API 几乎会立即免费。那里不需要异步。

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

我不明白这个。.NET Framework 和您的排队平台会为您解决这个问题。为什么要等待确认?

在公共交通中

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

在 NServiceBus 中

Bus.Publish(new YourMessage{Text = "Hi"});

我也想知道 SignalR 是否可以帮助我。

我应该这么认为!由于消息传递的异步特性,用户必须“等待”更新。如果您可以通过 SignalR 向用户“推送”更新来提供这些数据,那就更好了。

我是否完全脱离主题,我应该采取另一种方法吗?

也许,我仍然不确定你要去哪里。也许阅读以下资源。

资源:

http://www.udidahan.com/2013/04/28/queries-patterns-and-search-food-for-thought/ http://www.udidahan.com/2011/10/02/why-you-应该使用 cqrs-almost-everywhere%E2%80%A6/ http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/ http://www.udidahan。 com/2012/12/10/面向服务的API实现/

http://bloggingabout.net/blogs/dennis/archive/2012/04/25/what-is-messaging.aspx http://bloggingabout.net/blogs/dennis/archive/2013/07/30/partitioning-data -through-events.aspx http://bloggingabout.net/blogs/dennis/archive/2013/01/04/databases-and-coupling.aspx

于 2013-11-25T07:29:18.570 回答