编写长轮询WCF服务

25

我正在使用WCF编写一个长轮询服务。在进行负载测试时遇到了问题,当我达到5000个未处理请求时,出现以下错误:

The HTTP service located at (my service) is too busy.

我已经实现了一个WCF异步模式服务,消耗的工作线程/IO线程数量非常低(正如应该的那样)。句柄数也看起来不错。我想我正在遇到反DOS限制之一,只是找不到它。下面是我做的一些事情:

我修改了注册表,以便MaxConcurrentRequestsPerCPU不是问题。确实,ASP.NET排队请求的数量保持为0。

我在Web配置中设置了服务节流,因此这不应该是问题。 WCF跟踪没有显示任何由于这个原因而引发的异常。

我使用了一个自定义绑定,其中不包括任何安全性等内容。 它只有编码和传输(httpTransport)。

我修改了machine.config以提高requestQueueLimit:以下是该文件的processModel元素:

<processModel enable="true" 
  timeout="Infinite" 
  idleTimeout="Infinite" 
  shutdownTimeout="0:00:05" 
  requestLimit="Infinite" 
  requestQueueLimit="15000" 
  restartQueueLimit="10" 
  memoryLimit="60" 
  webGarden="false" 
  cpuMask="0xffffffff" 
  userName="machine" 
  password="AutoGenerate" 
  logLevel="Errors" 
  clientConnectedCheck="0:00:05" 
  comAuthenticationLevel="Connect" 
  comImpersonationLevel="Impersonate" 
  responseRestartDeadlockInterval="00:09:00" 
  responseDeadlockInterval="00:03:00" 
  maxWorkerThreads="250" 
  maxIoThreads="250" />

然而,我仍然面临这个限制(该机器可以处理它,系统的其余部分都异步返回到消息队列系统)。

还有其他人能想到的吗?

我使用的是WindowsServer 2008R2上的IIS 7.5。 Asp.NET 3.5SP1。


更多信息:当我收到以上错误时,ASP.Net v2.0.50727的“请求被拒绝”性能计数器会跳高。文档指出,当请求队列已满时会发生这种情况。请求队列性能计数器为0,从未动过。

如果我增加最大工作进程数量,我可以超过5K并发请求。


你使用的是哪种实例模型?有没有可能达到了会话限制?调整实例和并发模式可能是另一个需要考虑的地方... http://msdn.microsoft.com/zh-cn/magazine/cc163590.aspx - Wagner Silveira
这是一个值得思考的想法。我曾经在某个时候改变了InstanceContextMode=Single,ConcurrencyMode=Multiple。但是我已经恢复了以调查其他问题。然而,我认为这可能是ASP.NET限流问题。我会尝试一下。我的SessionMode=NotAllowed。 - Ted Carroll
所以,不,更改并发模式没有帮助。 - Ted Carroll
2
你的服务限流设置是什么?... ... - Maxim
你的HTTP绑定是否阻止了keep-alives?你可能能够增加最大并发TCP连接数,但最终你会达到上限。 - ssamuel
显示剩余2条评论
4个回答

3

来源:http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx

对于v2.0和v3.5,设置一个DWORD注册表值@ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0\MaxConcurrentRequestsPerCPU = 5000. 重新启动IIS。

对于v3.5,您还可以在aspnet.config文件中设置<system.web><applicationPool maxConcurrentRequestsPerCPU="5000"/></system.web>。如果两个地方都设置了该值,则aspnet.config设置会覆盖注册表设置。

对于v4.0,默认的maxConcurrentRequestsPerCPU为5000,因此您不需要进行任何操作。

增加HTTP.sys队列限制,默认值为1000。如果操作系统是x64且内存为2 GB或更多,则将其设置为5000应该没问题。如果太低,您可能会看到HTTP.sys拒绝带有503状态的请求。打开IIS管理器并为您的应用程序池更改“队列长度”的值。

如果您的ASP.NET应用程序使用Web服务(WFC或ASMX)或System.Net通过HTTP与后端通信,则可能需要增加connectionManagement/maxconnection。对于ASP.NET应用程序,这受到autoConfig功能的限制。这意味着在四核处理器上,您最多可以将12 * 4 = 48个并发连接到IP端点。因为这与autoConfig绑定在一起,所以在ASP.NET应用程序中增加maxconnection的最简单方法是从Application_Start编程设置System.Net.ServicePointManager.DefaultConnectionLimit。例如,将该值设置为您的应用程序预计使用的并发System.Net连接数。我将其设置为Int32.MaxValue,并没有任何副作用,因此您可以尝试一下-实际上,这是本机HTTP堆栈WinHTTP中使用的默认值。如果无法通过编程方式设置System.Net.ServicePointManager.DefaultConnectionLimit,则需要禁用autoConfig,但这意味着您还需要设置maxWorkerThreadsmaxIoThreads。如果不使用经典/ISAPI模式,则不需要设置minFreeThreadsminLocalRequestFreeThreads


1

1

IIS是否限制打开连接的数量?我认为在IIS中的网站或Web应用程序上有一个可以做到这一点的设置。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接