如何提高ASP.Net Web服务的性能



我们的应用程序中有一个旧的ASP.Net asmx Web服务,它有时会接收批量请求。单个请求的服务耗时不到5秒。但当它收到20个或更多的并发请求时,需要一分钟以上的时间。以下是它的实现方式,

1( 接收来自外部客户端的带有输入数据的请求

2( 根据验证后的输入数据,将从数据库中获得一个请求的20种可能性

3( 然后,它将使用foreach迭代所有20种可能性,并根据可能性数据从其他外部服务或数据库中获得解决方案。在旧的实现中,我们使用Parallel.Foreach并行执行所有20个调用(服务调用或DB调用(,以提高性能。

4( 之后,服务将把所有20个解决方案发送回客户端。

这种旧方法适用于少量(1或2(请求,考虑到外部服务调用需要2-3秒,asmx服务的响应时间非常快(不到5秒(。但当并发请求数超过20时,这种方法需要60秒以上专家分析,并通过导致请求排队等待线程分配。

因此,我们得到了一个建议,用端到端的异步/等待实现取代并行扩展并完成服务。我已经实现了端到端的异步/等待,还用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内部的外部服务调用/DB调用。但是,对于单个请求,这些服务响应非常快。异步实现在完成服务调用方面比并行扩展实现花费更多的时间。

我认为,如果单个请求的时间少于5秒,那么批量请求的服务时间不应该超过20秒。

有人能告诉我,在这里应该如何提高表现吗?

提前谢谢。

问候,

拉古。

看起来这里同时发生了很多事情。我相信你有一个导致许多副作用的问题。

我将假设您的服务器在CPU和内存方面足够处理并发连接(尽管CPU 100%让我怀疑(。

在我看来,你的问题是,并行任务(或线程(争夺相同的资源。这就解释了为什么多个请求需要花费更多的时间,以及为什么异步模式需要更多的时间。

让我解释一下:

实践中的问题

并行实现:1或2个请求需要最少的同步,所以即使它们竞争相同的资源,也应该是可以的。

当20个线程试图访问相同的资源时,会发生很多事情,并且会出现一种称为活锁的情况。

当您切换到async时,没有请求等待线程(它们正在IO线程上等待(,因此会使问题变得更糟。

(我怀疑问题出在你的数据库上。如果你的数据库服务器是同一台机器,它也会解释利用率(。

解决方案

与其试图提高并行性,不如找到有争议的资源并找出问题所在。

如果它在您的数据库中(最有可能的情况(,那么您需要确定导致问题的查询并修复它们(索引、统计信息、查询计划等等(。显示锁和查询执行计划的数据库分析器是您的朋友。

如果问题出现在代码中,请尽量减少竞争条件并改进算法。

要获得查找位置的提示,请使用Visual Studio评测工具:https://learn.microsoft.com/en-us/visualstudio/profiling/profiling-feature-tour?view=vs-2019或任何外部.net评测软件。

最新更新