【发布时间】:2021-02-22 02:59:16
【问题描述】:
我们的应用程序中有一个旧的 ASP.Net asmx Web 服务,它有时会接收批量请求。单个请求的服务时间不到 5 秒。但是当它收到 20 个或更多并发请求时,它需要一分钟多的时间。以下是它的实现方式,
1)接收来自外部客户端输入数据的请求
2)验证后根据输入数据从数据库中获取20种可能性
3) 然后它将使用 foreach 迭代所有 20 种可能性,并根据可能性数据从其他外部服务或数据库中获取解决方案。在旧实现中,我们使用 Parallel.Foreach 并行执行所有 20 个调用(服务调用或 DB 调用)以提高性能。
4) 之后,Service 会将所有 20 个解决方案发回给客户端。
考虑到外部服务调用需要 2-3 秒,这种旧方法适用于少数(1 或 2 个)请求,并且 asmx 服务的响应时间非常快(不到 5 秒)。但这种方法需要的时间超过当并发请求数量超过 20 时,为 60 秒。根据专家分析,并发请求将 CPU 利用率推至 100% 和线程池饥饿,并导致请求排队等待线程分配。
因此,我们建议用端到端的异步/等待实现替换并行扩展和完整的服务。我已经实现了端到端的异步/等待,并且还在 TPL 中用 Task.WhenAll 替换了 Parallel.foreach。但是在这个实现之后响应时间增加了很多。对于单个请求 20 秒,对于批量请求则需要 2 多分钟。
我还尝试使用 async foreach 代替 parallel.foreach,如下文所述,但性能仍然很差。
https://stackoverflow.com/questions/14673728/run-async-method-8-times-in-parallel/14674239#14674239
根据日志,基本问题是在旧的并行或新的异步/等待实现中,foreach 内部的外部服务调用/数据库调用。但是对于单个请求,这些服务响应非常快。与并行扩展实现相比,异步实现在完成服务调用方面需要更多时间。
如果单个请求少于 5 秒,我认为批量请求的服务时间不应超过 20 秒。
任何人都可以请我在这里提高性能的方法是什么?
提前致谢。
问候,
拉古。
【问题讨论】:
-
您可以考虑在您的应用和数据库之间添加一个缓存层,假设缓存一些频繁请求的数据与您的应用的功能兼容。
标签: c# asp.net web-services async-await parallel-processing