2013-03-17 138 views
0

,我就一直在生产工作几年的应用,但在提高频率已经expericing的UI(ASP的WebForms)和服务(WCF)之间超时。自从我们推出以来,用户数量和数据量已经显着增加。WCF服务和超时

本来,我们将原因归结到业绩不佳的SQL Server群集(该服务使用),并迁移到一个更强大的集群。但是,问题依然存在,并且似乎越来越多,我们每天收到的超时时间越来越长。

我们聘请了我们的DBA,但无法隔离SQL Server上的瓶颈。我还通过测试控制台应用程序直接调用服务来执行测试,并且问题也出现在那里,导致我认为问题不在WebForms中,而是在于WCF服务。

我就如何解决这一理论(并开始解决它)损失,因为它只有在看似高流量的情况下出现。

是否有与WCF和可扩展性的已知问题,或者是更有可能的是目前实施的服务是有缺陷?

+0

没有更多的细节,很难给出答案。 WCF服务使用什么样的绑定?它是SOAP还是REST?此外,超时可能表明服务中出现了问题(即未处理异常并且客户端超时等待响应)。你有没有启用WCF跟踪? – Tim 2013-03-18 05:46:09

+0

@Tim我们正在使用基于SOAP的BasicHTTPBinding。我会研究追踪。 – 2013-03-19 01:58:56

回答

1

我怀疑这个问题与SQL服务器和应用层之间的交互有关。我会假设你没有在应用程序中使用APM,因为你没有提及它。更不用说,在大多数人的脑海里,APM是为了加快UI的工作,对吗?

科学位,集中

ASP.Net/IIS默认给你的线程数量有限。记住线程是昂贵的,每个线程占用调度程序时间并以各种栈的形式占用内存,什么不是。这几乎是世界上所有计算机的缺陷。

在.NET中,所有工作都是在线程上完成的。因此,当没有空闲线程时,IIS会将请求放入队列以等待线程。现在,通常你会想如果所有的线程都在使用中,我们会有很高的CPU利用率。这是错误的。通常对于现代CPU,大部分时间他们都是I/O饿死,这意味着他们正在睡觉。

在这种情况下,一般什么情况是几个请求进来,自己的线程,谁然后打数据库的每个球。然后他们等待(睡眠)。您的CPU使用率为0%,而您的所有线程都在使用中。更多的请求进来了,他们被放入队列中。数据库请求返回,并且一些请求被出队(但不是全部)。然后队列上的请求超时。

Moar Thread!

我们如何解决这个问题?显然,我们希望尽可能快地从IIS队列中取出尽可能多的工作,并将其转移到SQL服务器上,对吧?所以显然的答案是增加线程的数量,对吧?现在,正如我前面提到的那样,线程很昂贵,所以如果你有一个强大的SQL服务器,你的应用服务器仍然会在SQL服务器之前放弃这个幽灵,同时还有0%的CPU util。显然更多的线程不会让我们在我们想要的地方。

异步/等待神奇酱!

接受的解决方案是实际使用异步编程。

但是不是异步/等待UI和并行?

不是。它最经常在用户界面和并行化方面得到证明,因为它的获益最容易形象化。在1小时的演示中更难以模拟1M次点击/秒的服务。

因此,当我们向数据库发送一个查询,而不是在结果上休眠时,该线程跳转回IIS队列为下一个客户提供服务。当结果返回时,通知下一个可用线程并处理它。

因此,通过数据库调用的异步/等待,您可以最大化CPU /网络实用程序并忽略数据库延迟。事实上,你会发现你应该将瓶颈转移到SQL服务器上。

但我的API在哪里?

啊......这是问题所在。异步/等待是相当新的。你需要VS 2012和.net 4.5(以及sorta)来使用它。大多数数据库API还没有完全支持Async/Await。

例如实体框架,Microsoft的旗舰数据库技术只支持EF 6.0 ALPHA中的异步/等待(截至编写本文时),并且很可能仅适用于MS SQL SERVER。

+0

感谢您的彻底回应。我很想用异步方法重写服务,但是,我们只使用.NET FX 2,重写不在此范围内。除了其他线程外,你能否提出其他解决方案? – 2013-03-19 02:01:49

+1

更多的线程,更多的RAM,更多的盒子。这将被大大浪费。他们几乎都会在100%的时间内睡觉。问题是一个建筑问题。理论上只有数据库访问层需要修复。实际上,消费代码需要与其匹配。如果可以升级至少4.0,我有几点建议。但2.0/3.5真的不能让我访问微软所做的任何并发工作。 – Aron 2013-03-19 02:12:27

+1

@TFerrell嗯......想到你可以做的一些事情,可能会大大提高性能。没有胆小的一点。将中间层物理移动更靠近SQL层。添加缓存逻辑以减少SQL命中。这些或许是增加可用线程数量的最佳选择。 – Aron 2013-03-20 03:25:08