我的C#WCF服务的CPU周期限制是什么?

我的C#WCF服务的CPU周期限制是什么?,c#,.net,multithreading,wcf,topshelf,C#,.net,Multithreading,Wcf,Topshelf,一两天前,关于我们在那里运行的WCF服务,在我们的生产服务器上发生了一件非常奇怪的事情:似乎有什么事情开始加速,将所讨论的进程的CPU周期限制在一个内核上可用的CPU周期量,即使负载分布在所有内核上(过程不是将一个磁芯燃烧到100%使用率) 该服务主要是CRUD(创建、读取、更新、删除)服务,但存在一些长时间运行(可能需要20分钟)的服务调用除外。这些长时间运行的服务调用会踢出一个简单的线程,并返回void,以便不让客户端应用程序等待或中断WCF连接: // WCF Service Side

一两天前,关于我们在那里运行的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周期

在生产服务器上,它没有超过25%的CPU使用率(4个内核),当我们将CPU内核增加一倍到8个时,它没有超过12.5%的CPU使用率

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

其他值得一提的服务内容

  • 这是Windows服务
  • 它在TopShelf主机内运行
  • 问题不是在部署(无论如何,我们的服务)后开始的
  • 生产服务器正在运行Windows server 2008 R2数据中心
  • 开发人员计算机正在运行Windows 7 Enterprise
我们已经检查、反复检查和尝试过的事情:

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

有没有关于什么原因的想法?

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

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


我们使用一个名为LeanSentry的工具,它非常擅长识别这类问题。它会将自身作为调试器连接到IIS,并捕获所有执行进程的堆栈转储,然后告诉您是否大多数线程都被阻塞在同一位置。有一个免费试用,您可以花足够长的时间来解决此问题。

在我看来,ge就像是SQL数据库中的一个表上的锁。我会使用SQL management studio来分析这些语句,看看它是否能证实这一点

您还指出,您调用存储过程时可能希望让它也看到这一点


这一切在我看来就像是一个数据库问题

不知道你的网站是否没有应用程序池的线程它不是一个网站,它是一个内部应用程序的后端服务哇,你每次都在为此创建一个线程?为什么不使用
线程池
?它会在内部使用线程,比你的tea更明智m、 是的,该调用不会经常被命中,可能是一天一次或两次。线程池不是灵丹妙药,它们有自己的位置,而这不是其中之一。限制是不太可能的。很可能,因为您正在向数据库写入数据,所以您是数据库绑定的。向数据库添加更多负载并不能使其运行更快,这就是为什么添加线程没有帮助的原因n大量加载,然后暂停调试器。在大多数情况下,在数据库调用中会看到除一个线程外的所有线程都停止。