.net 为什么dotnet keepalive Http连接在第二个请求中失败,并带有“0”;服务器关闭了预期保持活动状态的连接;?

.net 为什么dotnet keepalive Http连接在第二个请求中失败,并带有“0”;服务器关闭了预期保持活动状态的连接;?,.net,apache,dotnet-httpclient,keep-alive,servicepoint,.net,Apache,Dotnet Httpclient,Keep Alive,Servicepoint,我有一个dotnetframework应用程序,它向运行Apache的远程服务器执行postapi请求。它会间歇性失败,并出现以下错误: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server. 当通过keepalive TLS连接向服务器发出第二次请求时,就会发生这种情况,因此在高负载的生产系统中发生的频率更高,在开发环境中发

我有一个dotnetframework应用程序,它向运行Apache的远程服务器执行postapi请求。它会间歇性失败,并出现以下错误:

The underlying connection was closed: A connection that was expected to be kept alive was closed by the server. 
当通过keepalive TLS连接向服务器发出第二次请求时,就会发生这种情况,因此在高负载的生产系统中发生的频率更高,在开发环境中发生的频率更低或根本不存在这种情况

我们已尝试:

  • 禁用
    Expect:100 Continue
    标头行为(
    ServicePoint.Expect100Continue=false
  • 启用TCP保持活动状态(
    ServicePoint.SetTcpKeepAlive()
禁用HTTP保持活动似乎可以解决此问题。(
HttpWebRequest.KeepAlive=false


有没有一种方法可以在不禁用http保持活动的情况下解决此问题?

Apache设置
KeepAliveTimeout
在关闭空闲保持活动连接之前默认为5秒不活动。()

这会导致以下情况:

  • dotnet打开与apache的连接并发出一条POST
  • apache返回一个200 OK
  • 连接处于“空闲”状态,等待另一个请求
  • 2s后,dotnet打开一个新的HttpWebRequest并对其调用GetRequestStream(),以准备写入请求。由于池中存在空闲连接,因此将使用该连接
  • 5s后(
    KeepAliveTimeout
    ),apache发送一个FIN数据包来关闭底层连接
  • 在(比如)30秒后,dotnet尝试写入流,该流尝试使用现在已失效的套接字,但立即失败,导致
    底层连接关闭:服务器关闭了预期保持活动状态的连接。
  • 这在大型POST调用(例如,调用SOAP API)中尤其是一个问题,在这种情况下,形成有效负载可能需要相当长的时间

    可能的解决办法是:

  • 在开始发送数据之前,不要调用HttpWebRequest.GetRequestStream()
  • 禁用保持活动状态(
    HttpWebRequest.KeepAlive=false
    )。但是,请注意,如果应用程序中的任何其他线程正在使用keep alive,则会出现问题(上面的两个请求可能位于完全不同的线程中)
  • 最健壮的解决方案似乎是实现应用程序级重试

  • 重要的是,这种行为(将流锁定到套接字)似乎只在dotnet framework中发生,而不是在dotnet 5/core中发生。

    Apache设置
    KeepAliveTimeout
    在空闲保持活动连接关闭之前默认为5秒不活动。()

    这会导致以下情况:

  • dotnet打开与apache的连接并发出一条POST
  • apache返回一个200 OK
  • 连接处于“空闲”状态,等待另一个请求
  • 2s后,dotnet打开一个新的HttpWebRequest并对其调用GetRequestStream(),以准备写入请求。由于池中存在空闲连接,因此将使用该连接
  • 5s后(
    KeepAliveTimeout
    ),apache发送一个FIN数据包来关闭底层连接
  • 在(比如)30秒后,dotnet尝试写入流,该流尝试使用现在已失效的套接字,但立即失败,导致
    底层连接关闭:服务器关闭了预期保持活动状态的连接。
  • 这在大型POST调用(例如,调用SOAP API)中尤其是一个问题,在这种情况下,形成有效负载可能需要相当长的时间

    可能的解决办法是:

  • 在开始发送数据之前,不要调用HttpWebRequest.GetRequestStream()
  • 禁用保持活动状态(
    HttpWebRequest.KeepAlive=false
    )。但是,请注意,如果应用程序中的任何其他线程正在使用keep alive,则会出现问题(上面的两个请求可能位于完全不同的线程中)
  • 最健壮的解决方案似乎是实现应用程序级重试
  • 重要的是,这种行为(将流锁定到套接字)似乎只发生在dotnet framework中,而不是dotnet 5/core中