争用、 性能差、 和死锁,可以从 ASP.NET 应用程序对 Web 服务的调用

重要说明:本文是由 Microsoft 机器翻译软件进行的翻译并可能由 Microsoft 社区通过社区翻译机构(CTF)技术进行后期编辑,或可能是由人工进行的翻译。Microsoft 同时向您提供机器翻译、人工翻译及社区后期编辑的文章,以便对我们知识库中的所有文章以多种语言提供访问。翻译的文章可能存在词汇、句法和/或语法方面的错误。Microsoft 对由于内容的误译或客户对内容的使用所导致的任何不准确、错误或损失不承担责任。

点击这里察看该文章的英文版: 821268
症状
当您从 Microsoft ASP.NET 中应用程序对 Web 服务的调用,您可能会遇到争用、 性能差、 和死锁。客户端可能请求停止响应 (或"挂起"),或需要很长时间来执行报告。如果怀疑有死锁,能回收的工作进程。在应用程序事件日志中,您可能会收到以下消息。
  • 如果您使用的 Internet Information Services (IIS) 5.0,应用程序日志中收到以下消息:

       Event Type:     Error   Event Source:   ASP.NET 1.0.3705.0   Event Category: None   Event ID:       1003   Date:           5/4/2003   Time:           6:18:23 PM   User:           N/A   Computer:       <ComputerName>   Description:      aspnet_wp.exe  (PID: <xxx>) was recycled because it was suspected to be in a deadlocked state.      It did not send any responses for pending requests in the last 180 seconds.

  • 如果您使用的 IIS 6.0,则应用程序日志中收到以下消息:

       Event Type:     Warning   Event Source:   W3SVC-WP   Event Category: None   Event ID:       2262   Date:           5/4/2003   Time:           1:02:33 PM   User:           N/A   Computer:       <ComputerName>   Description:      ISAPI 'C:\Windows\Microsoft.net\Framework\v.1.1.4322\aspnet_isapi.dll' reported itself as      unhealthy for the following reason: 'Deadlock detected'.

  • 如果您使用的 IIS 6.0,则在系统日志中收到以下消息:

       Event Type:     Warning   Event Source:   W3SVC   Event Category: None   Event ID:       1013   Date:           5/4/2003   Time:           1:03:47 PM   User:           N/A   Computer:       <ComputerName>   Description:      A process serving application pool 'DefaultAppPool' exceeded time limits during shut down.      The process id was '<xxxx>'.

当您调用HttpWebRequest.GetResponse方法时,还可能会收到以下异常错误消息:
"System.InvalidOperationException: 若要完成此操作的线程池对象中没有足够的自由线程。"
在浏览器中,您还可能收到以下异常错误消息:
"HttpException (0x80004005): 请求超时。"
注意:本文还应用于直接进行HttpWebRequest请求的应用程序中。
原因
因为 ASP.NET 将辅助线程和调用可用来执行请求的完成端口线程数限制,则可能会出现此问题。

通常情况下,对 Web 服务的调用使用一个辅助线程执行的代码,将该请求发送和一个完成端口线程接收来自 Web 服务的回调。但是,如果该请求将被重定向或要求进行身份验证,呼叫可能会使用多达两个工作线程和两个完成端口线程。因此,可以在多个 Web 服务调用发生在同一时间耗尽托管线程池。

例如,假设线程池限制在 10 个工作线程,并且所有的 10 个工作线程当前正在执行代码的等待执行的回调。回调可从不执行,因为排队到线程池的任何工作项被阻止,直到某个线程变得可用。

争用的另一个潜在根源是maxconnection参数的System.Net命名空间用来限制连接数。通常情况下,这一限制就能如期作用。但是,如果多个应用程序试图同时对单个 IP 地址进行许多请求,线程可能需要等待一项可用连接。
解决方案
要解决这些问题,您可以调整 Machine.config 文件以最适合您的具体情况中的下列参数:
  • maxWorkerThreads
  • minWorkerThreads
  • maxIoThreads
  • minFreeThreads
  • minLocalRequestFreeThreads
  • maxconnection
  • executionTimeout
若要成功解决这些问题,请执行以下操作:
  • 限制在大约 12 种每个 CPU 的同时可以执行的 ASP.NET 请求的数量。
  • 允许 Web 服务回调自由使用在线程池的线程。
  • 选择适当的maxconnections参数的值。根据所使用的 IP 地址 andAppDomains 的选择。
注意:若要限制每个 CPU 的 12 到 ASP.NET 请求数的建议是一些任意的。但是,此限制证明适用于大多数应用程序。

maxWorkerThreadsmaxIoThreads

ASP.NET 使用以下两个配置设置来限制工作线程和完成线程所使用的最大数目:
<processModel maxWorkerThreads="20" maxIoThreads="20">
MaxWorkerThreads参数和maxIoThreads参数隐式地乘以 Cpu 的数量。例如,如果您有两个处理器,是以下的最大工作线程数:
2 * maxWorkerThreads

minFreeThreadsminLocalRequestFreeThreads

ASP.NET 还包含确定多少工作线程和完成端口线程必须是可用来启动远程请求或本地请求的以下配置设置:
<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="8">
如果没有足够的线程可用,请求进行排队,直到足够的线程都可以发出请求。因此,ASP.NET 将不会执行超过以下数目的请求在同一时间:
(maxWorkerThreads*Cpu 数)-minFreeThreads
注意:MinFreeThreads参数和minLocalRequestFreeThreads参数是不隐式相乘的 Cpu 数量。

minWorkerThreads

从 ASP.NET 1.0 Service Pack 3 和 ASP.NET 1.1 中,ASP.NET 还包含以下确定多少工作线程可能会使可立即用于远程请求提供服务的配置设置。
<processModel minWorkerThreads="1">
此设置控制的线程可以在更快的速度比从 CLR 的默认"线程优化"功能创建的辅助线程创建。这可能会突然填充由于 slow-down 后端服务器上的 ASP.NET 请求队列的设置使到服务中的 ASP.NET 请求、 请求来自客户端,或其它类似突然爆发,会导致在队列中的请求数量突然上升。MinWorkerThreads参数的默认值为 1。我们建议您将minWorkerThreads参数的值设置为下面的值。
minWorkerThreads = maxWorkerThreads / 2
默认情况下,不存在 Web.config 文件或 Machine.config 文件中的minWorkerThreads参数。此设置隐式乘以 Cpu 的数量。

maxconnection

Maxconnection参数确定多少能连接到特定的 IP 地址。参数如下所示:
<connectionManagement>    <add address="*" maxconnection="2">    <add address="http://65.53.32.230" maxconnection="12"></connectionManagement>
如果应用程序的代码引用该应用程序通过主机名而不是 IP 地址,该参数应如下所示:
<connectionManagement>    <add address="*" maxconnection="2">    <add address="http://hostname" maxconnection="12"></connectionManagement>
最后,如果除 80 之外的端口上承载的应用程序,该参数必须类似于以下的 URI 中包含非标准的端口:
<connectionManagement>    <add address="*" maxconnection="2">    <add address="http://hostname:8080" maxconnection="12"></connectionManagement>
在本文的前面部分中介绍的参数的设置是进程级别的全部内容。但是, maxconnection参数的设置应用到应用程序域级别。默认情况下,由于此设置将应用于应用程序域级别,您可以创建最多两个连接到特定的 IP 地址从每个应用程序域在过程中。

executionTimeout

ASP.NET 使用以下配置设置来限制请求执行时间:
<httpRuntime executionTimeout="90"/>
您还可以使用Server.ScriptTimeout属性来设置此限制。

注意:如果您增加executionTimeout参数的值,您可能需要修改processModel responseDeadlockInterval参数的设置。

建议

本部分中建议的设置可能不适用于所有应用程序。但是,以下附加信息可以帮助您进行相应的调整。

若要进行一次 Web 服务调用单个 IP 地址从每个 ASPX 页面,Microsoft 建议您使用以下配置设置:
  • maxWorkerThreads参数和maxIoThreads参数的值设置为100
  • 设置的maxconnection参数的值 12 *N (在何处 N 为 Cpu 随时数了)。
  • 设置的minFreeThreads参数的值 88 *NminLocalRequestFreeThreads参数76 *N.
  • MinWorkerThreads50集: 该值。请记住, minWorkerThreads不是默认的配置文件中。您必须添加它。
其中的一些建议涉及一个简单的公式,其中涉及到的服务器上的 Cpu 数量。表示公式中的 Cpu 数的变量是 N.对于这些设置,如果您有启用超线程必须使用逻辑 Cpu 数而不是物理 Cpu 的数量。例如,如果您有具有超线程的四处理器服务器启用,则的值 N 在公式中将有8而不是4个。

注意:当您使用此配置时,您可以执行 12 ASP.NET 请求,每个 CPU 的最大一次因为100 - 88 = 12。因此,至少 88 *N 辅助线程和 88 *N 完成端口线程可用于其他用途 (如 Web 服务回调)。

例如,您有带四个处理器和启用超线程的服务器。根据这些公式,将本文中提到的配置设置使用下列值。
<system.web>	<processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50"/>	<httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"/></system.web><system.net>	<connectionManagement>		<add address="[ProvideIPHere]" maxconnection="96"/>	</connectionManagement></system.net>

此外,在使用此配置时,12 个连接是可用每个 CPU 每个每个应用程序域的 IP 地址。因此,在以下情形中,很少发生争用时请求正在等待连接和线程池不会用完:
  • Web 承载只有一个应用程序 (应用程序域)。
  • ASPX 页的每个请求生成一个 Web 服务请求。
  • 所有请求都是到相同的 IP 地址。
不过,使用此配置时,涉及下列任一方案可能使用太多的连接:
  • 到多个 IP 地址的请求。
  • 请求被重定向 (302 状态码)。
  • 请求需要身份验证。
  • 请求是由多个应用程序域。
在这些情况下,最好使用maxconnection参数和更高的minFreeThreads参数和minLocalRequestFreeThreads参数值较低的值。
状态
此行为是设计使然。
更多信息
如果您遇到性能不佳和争用以及 ASP.NET 的 IIS 7.0,请转到以下 Microsoft 博客:
参考
有关详细信息,请访问以下 Microsoft 开发人员网络 (MSDN) 网站:

警告:本文已自动翻译

属性

文章 ID:821268 - 上次审阅时间:01/10/2016 04:51:00 - 修订版本: 2.0

Microsoft .NET Framework 2.0, Microsoft ASP.NET 1.1, Microsoft ASP.NET 1.0

  • kbprb kbmt KB821268 KbMtzh
反馈