争用、 性能差、 和死锁时从 ASP.NET 应用程序调用 Web 服务

http://support.microsoft.com/?id=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请求的应用程序。

Collapse image原因

因为 ASP.NET 将辅助线程和调用可用于执行请求的完成端口线程数的限制,则可能会出现此问题。

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

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

争用的另一个潜在根源是maxconnection参数的System.Net命名空间用来限制连接数。 通常情况下,这一限制就能如期作用。 但是,如果许多应用程序尝试在同一时间为单个 IP 地址使许多请求,线程可能需要等待一项可用连接。

Collapse image解决方案

要解决这些问题,您可以调整以最适合您的情况的 Machine.config 文件中以下参数:
  • maxWorkerThreads
  • minWorkerThreads
  • maxIoThreads
  • minFreeThreads
  • minLocalRequestFreeThreads
  • maxconnection
  • executionTimeout
若要成功地解决这些问题,请执行以下操作:
  • 限制在大约 12 种每个 CPU 的同时可以执行的 ASP.NET 请求数。
  • 允许 Web 服务回调可随意使用中的线程池的线程。
  • 选择适当的值为maxconnections参数。您的选择基于 IP 地址和使用的应用程序域的数量。
注意: 若要限制每个 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
默认情况下, minWorkerThreads参数不存在于 Web.config 文件或 Machine.config 文件中。 此设置将隐式地乘以 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参数的值,可能需要修改 processModelresponseDeadlockInterval参数的设置。

建议

建议使用本部分中的设置可能不适用于所有应用程序中。

如果您要做如何为单个 IP 地址一个 Web 服务调用并将其保存在每个 ASPX 页面中,Microsoft 建议您使用以下配置设置:
  • maxWorkerThreads参数,并使用maxIoThreads参数的值设置为100
  • 设置为maxconnection参数的值 12 *N (位置 N 为 Cpu 的数量,有)。
  • 设置为minFreeThreads参数的值 88 *N 和的minLocalRequestFreeThreads参数76 *N.
  • 设置50minWorkerThreads的值。请记住,在配置文件中默认情况下不是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参数的值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值