【问题标题】:Unexplained CPU use in C#/WCF applicationC#/WCF 应用程序中无法解释的 CPU 使用情况
【发布时间】:2010-01-26 01:20:13
【问题描述】:

我有一个难以解释的麻烦问题。简而言之,我的网络场中的网络服务器上的 CPU 使用率高得令人费解。

我有大量用户访问两个前端 Web 服务器。 99% 的页面加载是 Ajax 请求,并提供一个简单的 JSON 序列化对象,Web 服务器使用 WCF 从后端检索该对象。在典型情况下(同样,可能是 99% 的请求),ASPX 页面所做的所有事情都是进行 WCF 调用以获取此数据,将其序列化为 JSON 字符串并返回。

对象非常小——一个 guid、几个短字符串、几个整数。

非典型情况是初始页面加载,它执行相同的操作(WCF 请求),但使用 asp:literals 将响应注入到页面的不同部分。

所有三台机器(2 个 Web 服务器,一个后端)都具有相同的硬件规格。我希望后端在这种情况下完成大部分工作,因为它管理所有数据、进行查找等。但是:后端的负载小于前端。后端是一个不错的 10-20% 的 CPU 负载。前端平均运行 30%,但它们遍布整个地图,有时会在 10 秒内达到 100% 的峰值,并且需要 600 毫秒来处理这些非常简单的页面。

当我在分析器 (ANTS) 中运行前端时,它会将 WCF 通信标记为占用了 80% 的 CPU 时间。这就是对 .NET 生成的 WCF 代理的全部调用。

WCF 设置:服务是完全并行的。我将实例设置为“单个”,并发设置为“多个”。我将服务上的 maxConnections 和 listenBacklog 打开到 256。在重压(500 个请求/秒)下,我看到前端服务器和服务之间打开了大约 75 个连接,所以它没有撞到那堵墙。我将安全设置为“无”。带宽使用量约为潜力的 1/20(在 100Mb/s 网络上为 4Mb/s)。

在客户端(Web 服务器)上,我为服务创建了一个静态 ChannelFactory。调用服务的代码如下:

service = MyChannelFactory.CreateChannel();
try {
   service.Call();
   service.Close();
} catch {
   service.Abort();
}

(简化,但你得到了基本的图片)

我不明白前端的所有这些负载是从哪里来的。奇怪的是,它从来不在 30%-90% 的范围内。它要么处于恐慌模式(100%),要么正常(30% 或更少)。不过,考虑到后端的负载,我预计这两台机器的负载都在 10% 或更少。内存使用、句柄等,似乎都是合理的。

再增加一个问题:当我记录在后端为这些调用提供服务所需的时间时,我得到的时间始终少于 15 毫秒(每分钟可能有一两个峰值到 30 毫秒)。在前端,这些调用最多可能需要 1 秒才能返回。我想这可能是因为 CPU 问题,但在我看来。

那么...有没有人知道在哪里看这种东西?我要探索的东西不多了。

澄清:WCF 服务托管在 Windows 服务中,并且正在使用 netTcp 绑定。另外,我将客户端上的 maxConnections 设置为 128,FWIW。

【问题讨论】:

  • @Moxen:有没有弄清楚问题出在哪里?
  • 我们也在 Windows 服务中托管了一个 NetTCP WCF 服务,在迁移到 .NET 4 后突然出现这种行为。您有任何更新吗?我们正在考虑转向基于 IIS/ASP.NET,但我不相信它会解决问题。

标签: c# asp.net wcf


【解决方案1】:

很难说可能会发生什么,但一个疯狂的猜测是某些东西正在达到争用点并且它正在旋转(而不是等待)。

您是否在前端服务器中增加了与后端服务器的允许 HTTP 连接数?你可以做到through the config file。我在 WCF 客户端中看到的一个常见问题是限制保留为默认值 2,这严重限制了客户端代理级别的并发性。

【讨论】:

  • 对-- 我的印象是它正忙着等待某事,但我不知道是什么。如果需要,它似乎仍有空间与服务建立更多连接。稍微详细说明一下——WCF 服务是作为 Windows 服务托管的,而不是作为 IIS 的一部分。我在绑定上将 maxConnections 设置为 128(顺便说一下,它是 netTcp)。
  • 这两件事不相关。我描述的问题与服务器无关(我同意您在那里做了正确的更改),而是在客户端上。默认情况下,HttpWebRequest(WCF 在内部使用)将与单个远程服务器的连接限制为一次 2 个并发 HTTP 连接(这是 HTTP 规范建议的)。这意味着无论您的服务器设置如何,您的客户端都可能会遇到争用。
  • HttpWebRequest 连接限制会影响 netTcp 绑定吗?我认为这不会发生,因为我确实看到两台机器之间有几十个打开的连接。在压力测试期间,连接从零开始,最终逐渐上升。并且套接字(根据 netstat)肯定处于“已建立”状态。
  • 糟糕!没有看到您提到您正在使用 Net.TCP :) 在那种情况下,不,它不适用。 Net.TCP 绑定在内部进行连接池,因此在更高的负载下,您可能会达到池的上限并且代码正在旋转等待连接被释放。可以配置一些连接池,但我似乎记得您必须使用自定义绑定才能这样做。看TcpTransportBindingElement.ConnectionPoolSettings:msdn.microsoft.com/en-us/library/…
  • 我应该补充一点,除了增加连接池大小之外,这可能有助于在那些 TCP 连接池设置中减少租用超时,以便更快地将空闲连接释放到池中。
【解决方案2】:

您是否考虑并测试了外部因素的可能性?

  • 流程回收?
  • 是否启用了动态压缩?

【讨论】:

  • 我首先想到的是进程回收。
  • 这些机器上除了 Web 服务器上的 ASP.NET 和后端的一个 WCF windows 服务之外没有运行其他任何东西。 “ASP.NET v2.0.50727/Application Restarts”计数器未显示任何重新启动正在进行。并且应用程序池未设置为在 X 次请求后自动重启。
猜你喜欢
  • 2021-07-20
  • 2019-10-30
  • 2018-02-05
  • 2012-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多