【问题标题】:HttpWebRequest Port ExhaustionHttpWebRequest 端口耗尽
【发布时间】:2015-11-10 14:25:59
【问题描述】:

我们正在使用 Windows 服务对内部 REST 服务进行非常频繁的 HTTP 调用(每秒 20-40 次调用),但注意到在服务运行几分钟后获得响应的时间很长。

查看netstat,有不少端口处于“TIME_WAIT”状态,看来我们的端口可能快用完了。

我们如何确保端口被重用?

【问题讨论】:

  • 您是否在请求实例完成后处理它们?
  • 你也使用很多线程吗?
  • 这真的是一个性能问题......你已经把它归结为你的问题的原因......我不相信它是。我想说这更有可能是不同问题的症状。
  • 共享您用于发出请求的代码对于了解您是否正在做一些阻止重用连接的事情非常必要。
  • @user2966445 如果您每秒发出 20-40 次调用并且它们完成的时间不超过一秒钟,那么我建议您将连接限​​制设置为大约 50-60 范围.如果您仍然遇到瓶颈,我建议您的问题出在其他地方,并且提高连接限制不是您问题的答案(例如服务器上的请求限制导致排队,无法正确终止和处理请求,因此连接可以重复使用等等...)

标签: c# asp.net .net visual-studio


【解决方案1】:

同时传出 HTTP 连接的数量有限制。您可以在创建 HttpWebRequest 对象之前使用 System.Net.ServicePointManager.DefaultConnectionLimit 静态属性来控制这一点

将其设置为高于我认为的默认值 2 的值可能是值得的。

如果这没有帮助,那么您还可以增加默认的ThreadPool 大小,以便您更快地创建更多请求。线程池只会逐渐增加其线程数 - 每半秒一个新线程,IIRC

【讨论】:

  • 谢谢,但是我们已经在 web.config 文件中设置了以下内容:
  • 此外,我们在提交请求时运行跟踪,GetRequestStream() 平均需要 0-1 毫秒,而 GetResponse() 方法有时需要 60,000 毫秒以上。我们可以看到接收端处理响应的时间不到 1000 毫秒,因此瓶颈在发送端。
  • @user2966445 您是否确保在完成任何响应等后处理它们?如果您这样做,则默认情况下 C# 应默认重用相同的底层网络连接(不是相同的请求,但这是不可能的)。
【解决方案2】:

我们如何确保端口被重用?不要将连接限制设置为几乎可以保证不会的值。

看起来有人在某个时候对 ServicePointManager 进行了恶作剧。我会限制此来源的 ServicePoint:以鼓励 http 管道和连接重用:

ServicePointManager.FindServicePoint(Uri).ConnectionLimit = someSensibleValue;

【讨论】:

  • 我们已经尝试在配置文件中设置最大连接数:
  • @user2966445 因此,临时端口的范围从 49152 到 65535... 或 16383。可以想象,使用如此高的值可能会耗尽。为什么这个主机需要超过10个左右?最佳情况下,您有多少同时未响应的请求?在通常情况下,您不应该需要比此值更多的连接。连接可以重复使用(除非远程主机是 http1.0,发出connection:close 标头,或终止连接)。如此高的值将是有害的,因为连接不会被重用,并且它们将过期并接近 TIME_WAIT。
【解决方案3】:

这可能与许多用户在使用 HttpClient 类和内部使用 HttpClient 的类时遇到的相同问题有关。由于 HttpClient 实现了 IDisposable 接口,您会发现许多开发人员都迫切希望将类的任何新实例包装在 using 语句中。只有一个问题。当 HttpClient 对象被释放时,附加端口保持阻塞 5 分钟“TIME_WAIT”,直到它们被操作系统释放。

我通常使用单个 HttpClient 实例(单例)并将完全限定的 URL 与异步调用结合使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-25
    • 2010-09-22
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多