一个基于Basic HTTP绑定的自托管WCF服务不支持超过1000个并发请求。

4
我已经在BasicHttpBinding上自托管了一个WCF服务,由一个ASMX客户端消费。我正在模拟并发用户负载,达到1200个用户。该服务方法需要一个字符串参数并返回一个字符串。交换的数据小于10KB。通过Thread.Sleep(2000)语句将请求的处理时间固定在2秒钟左右。没有其他操作。我已经删除了所有DB Hits /业务逻辑。

同样的代码在1000个并发用户下运行良好。但是当我将数量增加到1200个用户时,会出现以下错误。

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
   --- End of inner exception stack trace ---
   at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
   at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at WCF.Throttling.Client.Service.Function2(String param)

这个异常通常在DataContract不匹配和大数据交换时报告。但是进行负载测试时从未出现过。我已经浏览了足够的资料,并尝试了大多数选项,包括:
  1. 在服务器端启用Trace和Message日志记录。但没有记录到错误。
  2. 为了克服端口耗尽,将MaxUserPort设置为65535,TcpTimedWaitDelay设置为30秒。
  3. 将MaxConcurrent Calls设置为600,将MaxConcurrentInstances设置为1200。
  4. 将Open、Close、Send和Receive超时设置为10分钟。
  5. 将HTTPWebRequest KeepAlive设置为false。
在过去的两天里,我一直没有能够找到问题所在。
希望得到任何帮助。
谢谢。

微软不建议自行托管,这只是用于测试。我不知道自行托管的限制(也从未见过),但你可以简单地将其转换为服务托管。我认为服务托管中有一些自行托管中没有的其他选项,你可以尝试一下,也许能解决你的问题。 - Saeed Amiri
基于消息的激活和监控是我所了解到的一些选项,它们不是ServiceHost的一部分,而是WAS和基于IIS的托管的一部分。除此之外,我会尝试查看自托管是否有任何特定限制。感谢您指出这一点。 - Krishnan
2个回答

0

如果服务端的WCF日志中没有错误,我怀疑您正在遇到HTTP.SYS驱动程序层的某种限制,导致在服务应用程序看到请求之前被拒绝。我认为特定应用程序请求队列的默认限制可能是1000。

我不是HTTP.SYS的专家,但您可以运行以下命令来获取一些见解:

netsh http show servicestate

谢谢Chris。我会运行你建议的命令。我忘记加一个点了。当托管在IIS上时,相同的代码可以处理2000个用户负载而没有任何问题。 - Krishnan
@Krishnan:这意味着IIS会为自己配置HTTP.SYS。 - John Saunders
Chris,我正在WinXP Professional系统上运行代码,但无法使用“show service state”netsh命令。我认为它只支持Win2003及以上版本的操作系统,这些系统具有新的KERNEL HTTT.SYS堆栈。不确定这一点。 - Krishnan
1
@John,你说得对。IIS在幕后对HTTP.SYS进行了一些配置。有一堆与IIS6(HTTP)相关的HTTP设置可以进行调整。但是当我在IIS上运行代码时,这些设置中没有一个被触及。这让我想知道WCF HTTPListener从哪里读取其配置?我最新的发现是,在C:\WINDOWS\system32\Logfiles\HTTPERR文件夹中记录了一个“HTTP 503 QueueFull”错误。我还没有找到需要调整哪个设置来解决这个问题。 - Krishnan
@Krishnan:我想知道IIS托管环境是否比你的更有效率? - John Saunders
显示剩余4条评论

0
我曾在不同的服务器上看到类似的问题,这取决于它们的CPU和RAM。您没有提到服务器类型,升级方式(XP Pro还是Server 2003升级到Server 2008等)。我解决这个问题的方法是通过检查x:\Windows\Microsoft.NET\Framework[version]\config\machine.config文件。显然,通过IIS选择“无限制”连接并不意味着“无限制”连接。我遇到的连接数在同一毫秒内的11个请求后出现错误。
问题与来自同一源的连接数量有关。性能基准测试工具驻留在具有相同IP的同一台PC上。machine.config包含对来自同一源的连接数量的约束。

我已经尝试在Windows Server 2003和带有SP2的Windows XP Professional上运行自托管的WCF服务。使用VS2010 ULTIMATE评估版(每台机器* 6个用户),模拟客户端(每个客户端机器都是WinXP Box)。在XP Pro上使用IIS 5.1存在最大传入HTTP连接数的限制,设置为10。我认为你遇到的错误应该是在托管服务的IIS上的XP Box上发生的。但在我的情况下,它是自托管的。 - Krishnan

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