【问题标题】:What could be rate limiting CPU cycles on my C# WCF Service?什么可能会限制我的 C# WCF 服务上的 CPU 周期?
【发布时间】:2015-11-25 12:51:47
【问题描述】:

一两天前,关于我们在那里运行的 WCF 服务,我们的生产服务器上开始发生一些非常奇怪的事情:似乎 某事 开始将相关进程的 CPU 周期速率限制为 CPU 数量一个核心上可用的周期,即使负载分布在所有核心上(进程没有将一个核心消耗到 100% 使用率)

该服务主要只是一个 CRUD(创建、读取、更新、删除)服务,但存在一些长时间运行(可能需要长达 20 分钟)的服务调用除外。这些长时间运行的服务调用启动一个简单的线程并返回 void,因此不会让客户端应用程序等待或阻止 WCF 连接:

// WCF Service Side
[OperationBehavior]
public void StartLongRunningProcess()
{
    Thread workerThread = new Thread(DoWork);
    workerThread.Start();
}

private void DoWork()
{
    // Call SQL Stored proc
    // Write the 100k+ records to new excel spreadsheet
    // return (which kills off this thread)
}

在上述调用开始之前,服务似乎做出了应有的响应,快速获取数据以显示在前端。

当您启动长时间运行的进程,并且 CPU 使用率达到 100 / CPUCores 时,前端响应变得越来越慢,最终在几分钟后不再接受任何 WCF 连接。

我认为正在发生的事情是,长时间运行的进程正在使用操作系统允许的所有 CPU 周期,因为某些东西对其进行了速率限制,并且 WCF 无法接受传入的连接,更不用说执行请求。

在某些时候,我开始怀疑我们的虚拟服务器运行的集群是否以某种方式这样做,但后来我们设法在我们的开发机器上重现了这一点,客户端使用环回地址与服务通信,所以硬件防火墙是也不干扰网络流量。

在 VisualStudio 内部对此进行测试时,我设法启动了 4 个这些长时间运行的进程,并通过调试器确认所有 4 个进程都在不同的线程中同时执行(通过检查 Thread.CurrentThread.ManagedThreadId),但仍然只使用 100 / CPUCores 总计 CPU 周期。

在生产服务器上,CPU 使用率不会超过 25%(4 核),当我们将 CPU 核数翻倍至 8 时,CPU 使用率不会超过 12.5%。

我们的开发机器有 8 个核心,CPU 使用率也不会超过 12.5%。

其他值得一提的服务

  • 它是一个 Windows 服务
  • 它在 TopShelf 主机中运行
  • 在部署(我们的服务)后问题并未开始
  • 生产服务器正在运行 Windows Server 2008 R2 Datacenter
  • 开发机器正在运行 Windows 7 企业版

我们已经检查、仔细检查和尝试过的事情:

  • 将进程的优先级从正常更改为高
  • 已检查进程的处理器关联性是否不限于特定内核
  • [ServiceBehavior] 属性设置为 ConcurrencyMode = ConcurrencyMode.Multiple
  • 传入的 WCF 服务调用正在不同的线程上执行
  • 从仅在控制台应用程序中托管 WCF 服务的方程式中删除 TopShelf
  • 设置 WCF 服务限制值:

关于什么可能导致这种情况的任何想法?

【问题讨论】:

  • 想知道您的网站是否用完了应用程序池的线程
  • 它不是网站,它是内部应用程序的后端服务
  • 哇,您每次都为此创建一个线程?为什么不使用ThreadPool?它将比您的团队更明智地在内部使用线程。
  • 是的,这个电话不会经常被击中,可能一天一两次。 ThreadPool 不是灵丹妙药,它们有自己的位置,而这不是其中之一。
  • 极限不太可能。可能,因为您正在写入数据库,所以您是数据库绑定的。向数据库添加更多负载并不会使其运行得更快,这就是添加线程无济于事的原因。加载大量负载,然后暂停调试器。在大多数情况下,您会看到数据库调用中除了一个线程之外的所有线程都停止了。

标签: c# .net multithreading wcf topshelf


【解决方案1】:

必须有一个共享资源,一次只允许一个线程访问它。这将有效地一次只允许一个线程运行,并准确地创建您所拥有的情况。

处理器关联掩码是将进程限制为单个 CPU 的唯一方法,如果您这样做,您会看到一个 CPU 固定,而其他所有 CPU 空闲(这不是您的情况)。

我们使用了一个名为 LeanSentry 的工具,它非常擅长识别这类问题。它将作为调试器附加到 IIS 并捕获所有正在执行的进程的堆栈转储,然后告诉您大多数线程是否在同一位置被阻塞。有足够长的免费试用版供您解决。

【讨论】:

    【解决方案2】:

    在我看来,CPU 使用率就像是对 SQL 数据库中的表的锁定。我会使用 SQL 管理工作室来分析这些语句,看看它是否可以确认。

    您还表示您调用存储过程可能希望它也查看它。

    在我看来,这一切都只是一个数据库问题

    【讨论】:

      猜你喜欢
      • 2014-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      • 2010-09-19
      • 2021-04-11
      相关资源
      最近更新 更多