0

我工作的一个应用程序已经投入生产好几年了,但 UI(ASP WebForms)和服务(WCF)之间的超时频率越来越高。自从我们推出以来,用户数量和数据量已经显着增加。

最初,我们将问题归咎于性能不佳的 SQL Server 集群(服务使用该集群),然后迁移到功能更强大的集群。但是,问题仍然存在,并且我们每天收到的超时次数似乎在增加。

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

我不知道如何解决这个理论(并开始解决它),因为它只出现在看似高流量的情况下。

WCF 和可伸缩性是否存在已知问题,还是更有可能是当前的服务实现存在缺陷?

4

1 回答 1

1

我怀疑这个问题与 SQL 服务器和应用程序层之间的交互有关。我将假设您没有在应用程序中使用 APM,因为您没有提及它。更不用说,在大多数人看来,APM 是为了让 UI 工作得更快,对吧?

科学位,集中

默认情况下,ASP.Net/IIS 为您提供有限数量的线程。请记住线程是昂贵的,每个线程都占用调度程序时间并以各种堆栈的形式占用内存,等等。这几乎是世界上所有计算机的缺陷。

在 .net 中,所有工作都在线程上完成。因此,当没有空闲线程时,IIS 会将请求放入队列以等待线程。现在,通常你会认为如果所有线程都在使用中,那么 CPU 利用率就会很高。这是错误的。通常对于现代 CPU,大部分时间它们都处于 I/O 饥饿状态,这意味着它们正在休眠。

在这种情况下,通常会发生一些请求。每次启动他们自己的线程,然后访问数据库。然后他们等待(睡觉)。您的 CPU 利用率达到 0%,而您的所有线程都在使用中。更多的请求进来。它们被放入队列中。数据库请求返回,一些请求出列(但不是全部)。然后队列上的请求超时。

摩尔线!

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

异步/等待魔法酱!

公认的解决方案是实际使用异步编程。

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

不。它最常在 UI 和并行化中展示,因为它的收益最容易可视化。在 1 小时的演示中模拟 100 万次点击/秒的服务要困难得多。

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

因此,使用 async/await 进行数据库调用,您可以最大限度地利用 CPU/网络,并忽略数据库的延迟。事实上,你会发现你应该已经把瓶颈转移到了 SQL 服务器上。

但是我的 API 在哪里?

啊...这是问题所在。异步/等待是相当新的。您需要 VS 2012 和 .net 4.5(很好)才能使用它。此外,大多数数据库 API 还没有完全支持 Async/Await。

例如 Entity Framework,Microsoft 的旗舰 DB 技术仅支持 EF 6.0 ALPHA 中的 async/await(截至撰写本文时),并且很可能仅支持 MS SQL SERVER。

于 2013-03-18T06:56:23.480 回答