简体   繁体   English

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

[英]How to Improve ASP.Net Web Service performance

We have one old ASP.Net asmx webservice in our application which receives bulk requests at sometime.我们的应用程序中有一个旧的 ASP.Net asmx webservice,它有时会接收批量请求。 Service is taking less than 5 seconds for a single request.单个请求的服务耗时不到 5 秒。 But It is taking more than a minute when it receives 20 or more concurrent requests.但是当它收到 20 个或更多并发请求时,它需要一分钟多的时间。 Following is the way it is implemented,以下是它的实现方式,

1)receives a request with input data from external clients 1) 从外部客户端接收带有输入数据的请求

2)Will get 20 possibilities from database for one request based on input data after validation 2) 将根据输入数据验证后从数据库中获取 20 种可能性对一个请求

3)Then It will iterate all 20 possibilities using foreach and gets solutions either from other external service or data base based on possibility data. 3)然后它将使用 foreach 迭代所有 20 种可能性,并根据可能性数据从其他外部服务或数据库中获取解决方案。 Here in old implementation we have used Parallel.Foreach to perform all 20 calls (service calls or DB calls) parallely to improve the performance.在旧实现中,我们使用 Parallel.Foreach 并行执行所有 20 个调用(服务调用或 DB 调用)以提高性能。

4)After that Service will send back the all 20 solutions to the client. 4) 之后,Service 会将所有 20 个解决方案发回给客户端。

This old approach is working fine for few (1or 2 ) requests and resonse time of asmx service is very fast(less than 5 seconds) considering external service calls which are taking 2-3 seconds .But This approach is taking more than 60 seconds when the number of concurrent requests are more than 20.Concurrent requests are pushing CPU utilization to 100% and thread pool starvation as per experts analysis and there by causing requests to queue for threads allocation.这种旧方法适用于少数(1 或 2 个)请求,并且考虑到需要 2-3 秒的外部服务调用,asmx 服务的响应时间非常快(不到 5 秒)。但是这种方法需要超过 60 秒的时间并发请求数超过 20。根据专家分析,并发请求将 CPU 利用率推至 100% 和线程池饥饿,并导致请求排队等待线程分配。

So we got a recommendation to replace parallel extensions and complete service with async/await implementation from end to end.I have implemented async/await end to end and also replaced Parallel.foreach with Task.WhenAll in TPL.所以我们得到了一个建议,用端到端的 async/await 实现替换并行扩展和完整服务。我已经实现了 async/await 端到端,并在 TPL 中用 Task.WhenAll 替换了 Parallel.foreach。 But response time has increased a lot after this implementation.for a single request 20 secconds and it its taking more than 2 minutes for bulk requests.但是在这个实现之后响应时间增加了很多。对于单个请求 20 秒,它需要超过 2 分钟的批量请求。

I also tried async foreach in place of parallel.foreach as mentioned in below article but still performance is really bad.我还尝试了 async foreach 代替 parallel.foreach ,如下文所述,但性能仍然很差。

https://stackoverflow.com/questions/14673728/run-async-method-8-times-in-parallel/14674239#14674239 https://stackoverflow.com/questions/14673728/run-async-method-8-times-in-parallel/14674239#14674239

As per logs basic issue is with external service calls/DB calls inside foreach in both old parallel or new async/await implementations.But these service responses are very fast for a single request.根据日志,基本问题是在旧的并行或新的异步/等待实现中 foreach 内部的外部服务调用/数据库调用。但是对于单个请求,这些服务响应非常快。 Async implementation is taking more time in completing service calls than parallel extensions implementation.与并行扩展实现相比,异步实现在完成服务调用方面花费的时间更多。

I think service should not take more than 20 seconds for bulk request if it is lessa than 5 seconds for single request.如果单个请求少于 5 秒,我认为批量请求的服务不应超过 20 秒。

Can anyone please me what should be the way forward here to improve the performance ?任何人都可以请我在这里改进性能的方法是什么?

Thanks in advance.提前致谢。

Regards,问候,

Raghu.拉古。

Looks like a lot of things happening here at the same time.看起来很多事情同时发生在这里。 I believe you have on nderlying issue that causes many side effects.我相信您对导致许多副作用的潜在问题有所了解。

I will make the assumption that your server is sufficient in terms of CPU and memory to handle the concurrent connections (though the CPU 100% makes me wonder).我将假设您的服务器在 CPU 和内存方面足以处理并发连接(尽管 CPU 100% 让我感到疑惑)。

It seems to me that your problem, is that the parallel tasks (or threads), compete for the same resources.在我看来,您的问题是并行任务(或线程)争夺相同的资源。 That would explain why multiple requests take much more time and why the async paradigm takes even more.这将解释为什么多个请求需要更多时间以及为什么异步范式需要更多时间。

Let me explain:让我解释:

The problem in practice实践中的问题

Parallel implementation: 1 or 2 request need minimum synchronization, so even if they compete for the same resources, it should be fine.并行实现:1个或2个请求需要最少的同步,所以即使它们争夺相同的资源,也应该没问题。

When 20 threads, try to access the same resources, a lot is happening and you come to a situation known as livelock.当 20 个线程尝试访问相同的资源时,会发生很多事情,您会遇到一种称为活锁的情况。

When you switch to async, no requests await for a thread (they are waiting on the IO threads), so you make the problem even worse.当您切换到异步时,没有请求等待线程(它们正在等待 IO 线程),因此您会使问题变得更糟。

(I suspect that the problem is on your database. If your database server is the same machine, it would also explain the utilization). (我怀疑你的数据库有问题。如果你的数据库服务器是同一台机器,它也会解释利用率)。

The solution解决方案

Instead of trying to up the parallelism, find the contested resources and identify the problem.与其尝试提​​高并行度,不如找到有争议的资源并找出问题所在。

If it's in your database (most probable scenario), then you need to identify the queries causing the trouble and fix them (indexes, statistics, query plans and whatnot).如果它在您的数据库中(最可能的情况),那么您需要识别导致问题的查询并修复它们(索引、统计信息、查询计划等等)。 DB profilers showing locks and query execution plans are your friends for this.显示锁和查询执行计划的数据库分析器是您的朋友。

If the problem is in your code, try to minimize the race conditions and imporve your algorithms.如果问题出在您的代码中,请尝试最小化竞争条件并改进您的算法。

To get a hint of where to look for, use the Visual Studio profiling tools: https://docs.microsoft.com/en-us/visualstudio/profiling/profiling-feature-tour?view=vs-2019 or any external .net profiling software.要获得有关查找位置的提示,请使用 Visual Studio 分析工具: https : //docs.microsoft.com/en-us/visualstudio/profiling/profiling-feature-tour?view=vs-2019或任何外部 .网络分析软件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM