asp.net - 限制并发还是不限制并发? (在单个 ASP.NET 请求内)

标签 asp.net asynchronous concurrency .net-core scalability

关于如何限制异步 I/O 操作和/或其延续的并发性,有很多答案 - 使用自定义调度程序、SemaphorSlim 等。我的问题是:这样做有意义吗 在标准 ASP.NET MVC/WebAPI 场景中?

我们有一个典型的企业 API,用作面向客户的 SPA 的后端。许多 API 请求涉及调用数十个下游 Web 服务,目前我们已将其大部分转换为带有 TAP (async/await) 的异步 I/O。许多远程服务调用都是并行启动的,无需等待,然后使用 Task.WhenAll 批量等待。有时 WhenAll 是通过固定数量的任务完成的,有时我们对集合中的每个项目启动远程调用 - 这会导致生成未知(但通常很少,不到十几个)数量的任务,然后和 WhenAll 一起等待他们。

As I understand ,这会导致这些任务的延续(即反序列化其响应的逻辑)在线程池上进行调度。这引出了我的问题:并行运行这些受 CPU 限制的延续不会导致线程池承受过大的压力吗?我们是否应该开发某种中间件,通过将单个请求内启动的异步 I/O 任务调度到自定义调度程序来限制它们的并发性?

通过减少任何给定请求分配的 ThreadPool 线程数量,可以提高应用程序的可扩展性吗?这将允许在我们开始耗尽 ThreadPool 线程(或受到限制)之前服务更多并发请求通过线程池的增长)?

或者这毫无用处,我们应该简单地相信默认的 ThreadScheduler+ThreadPool 能够在任意数量的并发请求中将所有任务调度到可用的 CPU 核心?

仅供尝试回答的每个人引用:

这是一家非常大的公司相当成熟的系统,经过数十名专家(包括我自己)的仔细审查,正在为美国一个州生产,即将在国家一级生产。诸如“首先测量”、“了解您是否受 IO 与 CPU 限制”、“尝试 AppInsights”和“不要试图比 Microsoft 更聪明”等建议显然是我们自己首先考虑的事情。我们寻求的指导水平更像是:这里有人在美国国家层面实现了全异步 ASP.NET Web API 系统,并且拥有 async/WhenAll 并发的实际经验吗?

最佳答案

@tarun-lalwani 在评论中提出了一些重要观点

但我会提到永远不要预先优化的可靠建议。如今的中端台式机可以轻松处理 16 个线程池(通常可以处理数百个等待任务),一台好的服务器可以处理比这大得多的线程池,您的时间成本与更换或更换的成本是多少新服务器,可能不到 6 个月,很可能不到 3 个月。

任何性能问题都归结为瓶颈,系统的执行速度只能与最慢的瓶颈一样快。所以改善那些具体的瓶颈,在现实系统中,就是​​如何提高性能。如何扩展这组瓶颈就是如何提高可扩展性。台式机和服务器硬件之间仍然存在很多差异,因此我再次强调,在花费数周/数月的努力来修复“问题”之前,您需要查看这些东西的真实世界而非体外指标。可能不存在。

如上所述,GraphQL 允许您重新安排瓶颈出现的位置,使您能够更均匀地分布它们,以更好地利用您已有的硬件。许多更现代的设计模式也是如此。

总之,只有当某个流程成为问题时才对其进行限制才有意义。

关于asp.net - 限制并发还是不限制并发? (在单个 ASP.NET 请求内),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51143995/

相关文章:

asp.net - 如果其Exception.Message包含ASP.Net AJAX中的某些内容,则忽略并清除错误

asp.net - 使用 ASP.Net 缓存客户端图像

JavaScript 在 while 循环中等待异步函数

Go range over channel 死锁问题,我应该关闭 channel 吗?

构造函数中的 Java 内存可见性

Java ConcurrentLinkedQueue 而不是 List?

asp.net - 如何从 ASP.NET 调用 Windows 服务

asp.net - 存储应用程序变量

javascript - Nodejs异步调用,如何处理一个url上的多个请求

java - 安卓 : Notified when all Async calls are completed