【问题标题】:WebRequest and Resources - ASP.NET TimeoutWebRequest 和资源 - ASP.NET 超时
【发布时间】:2010-07-26 19:35:07
【问题描述】:

我有一个 ASP.NET Web 窗体应用程序,它在内部对 Web 服务进行许多 SOAP 和 REST 调用。 SOAP 调用是使用 Microsoft 自己的“包装”代码进行的。 REST 调用是从一个简单的 REST 客户端发出的。此客户端使用 Using 块来处理任何资源。

应用程序可以正常运行几个小时,但随后挂断。该站点将不再能够提供 asp.net 页面。我通过在其上放置一个 hello.htm 文件来测试该站点……它运行良好。所以肯定是ASP.NET引擎空间的问题。

感觉好像它已经用完了来自池的 webrequests。我可能会走得很远。我可以尝试什么?我应该看什么?重现问题需要几个小时。 在 IIS 上重新启动站点可以解决问题,但当然不是我们可以接受的真正解决方案。

错误开始和堆栈跟踪:
“/”应用程序中的服务器错误。

操作已超时 说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.Net.WebException:操作已超时

来源错误: 在执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常起源和位置的信息。

堆栈跟踪: [WebException:操作已超时] System.Net.HttpWebRequest.GetRequestStream() +5322142 System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] 参数) +103

更新和更多信息
自制的 REST 调用和 SOAP 都是同步完成的。
它们的寿命不长,大约需要 1 秒。
Web 服务托管在同一数据中心的 Tomcat 服务器(不同的机器)上。
.NET 应用程序调用 Tomcat 服务器上的 SOAP 和 REST 服务。

在挂起状态停留大约一个小时后,该应用程序以某种方式自行修复。想法? 如何监控 .NET 线程池? DefaultConnectionLimit 是否会影响自发起的出站连接?

分辨率 请参阅其他 cmets 的答案和... 1) 关闭您自己开发的 REST 代码中的所有流和响应/请求 (oops)
2) System.Net.ServicePointManager.DefaultConnectionLimit = 96;
// 默认值 = 12 次核心数
System.Net.ServicePointManager.MaxServicePointIdleTime= 3000;
// 默认值 = 100000(100 秒)
通过修复任何泄漏的代码并更快地使 IdleTime 超时,现在一切似乎都可以正常工作了

【问题讨论】:

  • 您调用的外部 SOAP 服务是否有任何使用限制?跟踪它正在调用的服务,看看你是否可以重复点击它,就像你在实践中点击它一样多次。所有页面都调用相同的服务吗?是所有 SOAP 调用都失败还是只有这一次失败?
  • 我可以使用 WinForms 客户端和另一个 ASP.NET Web 应用程序(相同的 IIS)从同一个框中点击它。此 IIS 站点超时的所有调用 REST 或 SOAP。应用程序日志将其列为 WebException Timeout
  • 如何查看这个应用程序占用了多少内存?我对导航 IIS 7 或 win2008 还不太熟悉
  • 有谁知道 IIS 7 上的 .NET 4.0 是否会比 IIS 7 上的 .NET 3.5 更好地处理大量 WebRequest 的创建和销毁?

标签: .net asp.net web-services httpwebrequest


【解决方案1】:

1) 你在使用异步 WebRequests 吗? 2)您的网络服务调用是否长期存在(意味着它们需要很长时间才能完成?) 3) 网络服务托管在哪里?是在同一台机器上吗? 4) REST 服务托管在哪里?与 asp.net 应用程序相同的机器还是不同的机器?

当请求进入 ASP.NET 服务器时,它会在线程池线程上进行处理。我不确定这是完成端口线程还是线程池线程。

无论如何,您的应用程序正在线程池线程上调用。在此线程上,您正在发出出站 HTTPWebRequest (HWR)。如果这个请求是同步的,它不应该占用任何额外的线程。但是,如果它是异步的,它将需要池中的另一个线程来完成。

现在,如果您创建的 HWR 返回到同一台服务器,并且该请求需要同一台服务器上的另一个线程来完成,那么您现在需要一个线程。将此与需要很长时间的 Web 服务结合起来,每个请求至少占用 2 个(最多 3 个)线程。如果您向 asp.net 服务器发出大量请求,服务器会很快达到最大线程池线程限制。

到目前为止,我假设您的代码中没有逻辑错误,并且您正确地处理了 HttpWebResponse 对象。

因此,当没有线程完成工作时,您的 HttpWebRequest 可能会抛出超时异常。

如果您的后端 Web 服务调用是针对同一台计算机的,并且您没有将 ServicePointManager.DefaultConnectionLimit 增加到您的场景的合理值,也可能会发生这种情况。例如,如果您的 asp.net 应用程序预计会同时收到 200 个请求,您应该设置 DefaultConnectionLimit = 200 + 一些合理的缓冲区。连接池中缺少连接也可能导致此问题。

解决方案:

我会首先设置 DefaultConnectionLimit。如果这不能解决问题,那么您需要监控 ASP.NET 性能计数器并查看 .Net 线程池是否已耗尽,这可能导致 webrequests 失败。

【讨论】:

  • 是的,DefaultConnectionLimit 会影响从您的应用程序启动的出站连接。作为第一个测试,我会尝试增加它以查看它是否可以解决您的问题。对于监视线程计数,您可以查看性能计数器 .NET CLR Locks 和线程数/当前物理线程数作为线程池中 # 个线程的代理。您还可以跟踪 asp.net 性能计数器,这些计数器跟踪排队的请求/执行的请求等
  • 在这一项上调用了 Microsoft 支持,这两个设置很关键-stackoverflow.com/questions/3363183
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-10
  • 2016-01-16
  • 2012-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
相关资源
最近更新 更多