是啥限制了我的 ASP.NET 应用程序可以与 Web 服务建立的同时连接数?
Posted
技术标签:
【中文标题】是啥限制了我的 ASP.NET 应用程序可以与 Web 服务建立的同时连接数?【英文标题】:What is limiting the # of simultaneous connections my ASP.NET application can make to a web service?是什么限制了我的 ASP.NET 应用程序可以与 Web 服务建立的同时连接数? 【发布时间】:2011-12-12 14:06:56 【问题描述】:我有一个 ASP.NET 4.0 应用程序在 64 位 Windows Server 2008 R2 Enterprise 计算机上运行在 IIS 7.5 上,具有大量 RAM、CPU、磁盘等。
对于每个 Web 请求,ASP.NET 应用程序都会连接到在同一台机器上运行的后端 Web 服务(通过原始套接字)。
问题:似乎有一些东西限制了与后端 Web 服务的同时连接数。令人怀疑的是,并发连接数达到了 16 个。
我发现这篇来自 Microsoft 的重要文章解释了如何调整 IIS 的设置以适应发出大量 Web 服务请求的 ASP.NET 应用程序:http://support.microsoft.com/?id=821268#tocHeadRef
我遵循了文章的推荐,但仍然没有运气。特别有趣的设置是maxconnection
设置,我什至碰到了999。
您知道其他可能会限制连接吗?
注意:当我将 IIS 从组合中剔除并让客户端直接连接到后端 Web 服务时,它会很高兴地打开我需要的任意数量的连接,所以我肯定后端不是瓶颈。它必须是 IIS/ASP.NET-land 中的东西。
这是machine.config
的相关部分,我确信应用程序正在读取它(通过appcmd.exe
验证):
<system.web>
<processModel autoConfig="false" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" />
<httpRuntime minFreeThreads="176" minLocalRequestFreeThreads="152"/>
<httpHandlers />
<membership>
<providers>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
</providers>
</membership>
<profile>
<providers>
<add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</profile>
<roleManager>
<providers>
<add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="AspNetWindowsTokenRoleProvider" applicationName="/"
type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
</system.web>
<system.net>
<connectionManagement>
<add address="*" maxconnection="999"/>
</connectionManagement>
</system.net>
【问题讨论】:
@DanB 有一个很好的观点 - 你如何测量并发连接数? @JeremyMcGee 我正在通过在服务器上运行 TCPView 来测量并发连接数,以查看 IIS 工作进程建立了多少后端连接。 Web 客户端是在独立机器上运行还是在同一台机器上运行? (检查是否存在客户端限制。) @JeremyMcGee 分离机器。每台机器 1 个客户端-服务器连接。此外,我们知道网络上的某个地方没有任何限制,因为当我们直接访问后端(也发生在 HTTP 上)时,我们不会遇到瓶颈。 Rob,你有没有找到一个明确的解决方案? 【参考方案1】:我意识到这个问题可能很老了,但你说后端在同一台服务器上运行。这意味着在不同的端口上,可能不是默认端口 80。
我了解到,当您使用“connectionManagement”配置元素时,如果端口号不同于默认的 80,则需要指定端口号。
链接:maxConnection setting may not work even autoConfig = false in ASP.NET
其次,如果您选择使用默认配置 (address="*") 扩展您自己的后端特定值,您可以考虑将特定值放在首位!否则,如果发出请求,* 首先匹配并采用默认的 2 个连接。就像您在 web.config 中使用该部分一样。
链接:<remove> Element for connectionManagement (Network Settings)
希望对某人有所帮助。
【讨论】:
【参考方案2】:在进行性能测试时,我采用的衡量标准是 RPS,即服务器在可接受的延迟内每秒可以处理多少个请求。
理论上,一台服务器只能同时运行与其上核心数量一样多的请求。
看起来问题不在于 ASP.net 的线程模型,因为它可能服务于数千个 rps。似乎问题可能出在您的应用程序上。您是否使用任何同步原语?
还有你的网络服务的延迟是多少,它们响应速度是否很快(在微秒内),如果不是,那么你可能需要考虑异步调用,所以你最终不会阻塞
如果这没有产生什么结果,那么您可能需要使用 Visual Studio 或 Redgate Profiler 来分析您的代码
【讨论】:
【参考方案3】:这里提供的大多数答案都是针对后端 Web 服务的传入请求数,而不是您可以从 ASP.net 应用程序发出的传出请求数您的后端服务。
在此处限制您的请求率的不是您的后端 Web 服务,而是您的调用应用程序愿意与同一端点(同一 URL)建立的打开连接数。
您可以通过将以下配置部分添加到您的 machine.config 文件中来消除此限制:
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="65535"/>
</connectionManagement>
</system.net>
</configuration>
如果您想要 50 或 100 个并发连接,您当然可以选择一个更合理的数字。但上述内容将其打开至最大值。您还可以为上面的开放限制规则指定一个特定的地址,而不是表示所有地址的“*”。
MSDN Documentation for System.Net.connectionManagement
Another Great Resource for understanding ConnectManagement in .NET
希望这能解决您的问题!
编辑: 糟糕,我确实看到您在上面的代码中提到了连接管理。我将留下我的上述信息,因为它与未来有同样问题的询问者有关。但是,请注意目前在最新的服务器上有 4 个不同的 machine.config 文件!
.NET Framework v2 在 32 位和 64 位下运行,.NET Framework v4 也在 32 位和 64 位下运行。根据您为应用程序池选择的设置,您可以使用这 4 个不同的 machine.config 文件中的任何一个!请检查通常位于此处的所有 4 个 machine.config 文件:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config【讨论】:
是的,我覆盖了那个基础。无论如何,谢谢@BenSwayne!我确认我修改了正确的machine.config
(64 位 4.0)。
@RobSobers:在这种情况下,我会对实现代码有点怀疑。也许您的线程用完了或其他什么?您可以将您的 TcpClient Web 服务调用代码放入控制台应用程序中,看看您是否可以获得更好的请求率?这将证明它是 IIS 特定配置还是更广泛的 .NET 配置或您的代码。
这条线是否进入客户端机器?
谢谢,您的设置与来自codeproject.com/Articles/133738/… 的 processModel twekaing 相结合,修复了“ISAPI 'C:\windows\Microsoft.Net\Framework\v2.0.050727\aspnet_isapi.dll' 报告为不健康的以下原因:“检测到死锁”问题
@BenSwayne 同样的概念是否也适用于 SMTP 连接?我正在设计一个批量电子邮件发送应用程序,所以这个 ConnectionManagement 属性在发送批量邮件时也会有用吗(对 mail.send 函数使用多线程)?【参考方案4】:
您可能正在使用基于 WCF 的 Web 服务引用吗?默认情况下,ServiceThrottlingBehavior.MaxConcurrentCalls 为 16。
您可以尝试更新服务引用行为的 <serviceThrottling>
元素
<serviceThrottling
maxConcurrentCalls="999"
maxConcurrentSessions="999"
maxConcurrentInstances="999" />
(请注意,我建议使用上述设置。)有关如何配置适当的<behavior>
元素的更多信息,请参阅MSDN。
【讨论】:
我希望我们是,但我们不是。正在使用的服务在另一台机器上的 Apache/Python/mod_wsgi 中运行,正如 Rob 所说,这显然不是问题。 服务参考在客户端。您的客户如何使用 Apache 服务? 就像 John 所说的:限制是在使用 Web 服务的客户端上设置的。也许“您的服务行为”这句话有点误导。表述为“您的服务参考行为”是否更有意义? @john 它通过TcpClient
使用(该服务提供自定义二进制 blob,而不是 WCF/SOAP 或类似的)。如果您使用ServiceHost
,而不是TcpClient
,这些配置选项似乎会纯粹影响您;我错过了什么吗?
为什么不使用“添加服务参考”?【参考方案5】:
您是否尝试过以编程方式设置静态DefaultConnectionLimit 属性的值?
这里是关于真正令人头疼的信息的一个很好的来源...ASP.NET Thread Usage on IIS 7.5, IIS 7.0, and IIS 6.0,其中包含框架 4.0 的更新。
【讨论】:
我想这应该没关系,但我还是要试试。 这是我们几年前修复它的方法。我们遇到了并发问题,这似乎解决了问题。 Net.ServicePointManager.DefaultConnectionLimit = 1000 是我们使用的。您必须在创建连接类之前设置它。【参考方案6】:如果它没有在托管 Web 服务消耗品的 Web 服务或应用程序或服务器(Apache 或 IIS)中定义,那么您可以创建无限连接直到失败
【讨论】:
【参考方案7】:请参阅此页面的“线程”部分:http://msdn.microsoft.com/en-us/library/ff647786.aspx,以及“连接”部分。
您是否尝试过提高您的 processModel 设置的 maxconnection 属性?
【讨论】:
是的,我有。但是您引用的那篇文章指出了一些有趣的东西,而其他关于该主题的文章却忽略了提及:maxconnection
属性不适用于 local Web 服务调用。在这种特殊情况下,Web 服务 是本地的,但我们在服务不是本地的另一个环境中遇到了同样的问题。
@RobSobers - 我认为上面的链接值得一看。检查关于 minLocalRequestFreeThreads
的部分 - 如果可用线程的数量,此工作进程使用此设置将来自 localhost 的请求(其中 Web 应用程序调用同一服务器上的 Web 服务)排队在线程池中低于这个数字。此设置类似于 minFreeThreads,但它仅适用于使用 localhost 的请求。
@Ahmad 是的,我也设置了minLocalRequestFreeThreads
(请参阅问题中的machine.config
。以上是关于是啥限制了我的 ASP.NET 应用程序可以与 Web 服务建立的同时连接数?的主要内容,如果未能解决你的问题,请参考以下文章