简单的内部 HTTP GET 请求因 SocketException 而失败:现有连接被远程主机强行关闭
Simple internal HTTP GET request failing due to SocketException: An existing connection was forcibly closed by the remote host
我有一个简单的健康检查系统,它向内部 URL 发送一个简单的 HTTP GET 请求,这是一个需要身份验证的 MVC 网络应用程序。例如,如果您向 https://{{IPAddress}}/MyMvcApp
发送获取请求,应用会将您重定向到 https://{{LB Host}}/MyMvcAppAuth
.
private static void UsingHttpGetRequest(string uri, Action<HttpWebResponse> action)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback
(
delegate { return true; }
);
Log("Sending the HTTP Get request...");
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Log($"Got a response! Status: {response.StatusCode}");
action(response);
}
}
我的服务器场中有两台服务器。这段代码在其中一台服务器上运行时,运行正常,但是另一台服务器出现了这个问题:
Exception: System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
- 我比较了服务器之间的 IIS 配置设置,发现没有明显差异。
- 我比较了注册表项,发现两台服务器都没有注册表项“SchUseStrongCrypto”,但两台服务器上肯定都启用了 TLS 1.2。
- 已验证两者都安装了 .NET v4.0.30319。
我对此思考得越多,就越得出这样的结论:F5 负载平衡器拒绝来自场中其中一台服务器的请求的 302 重定向。你们有什么感想?拒绝这些请求的负载平衡器可能存在 firewall/misconfiguration 问题?
另一种方法。
public static bool CheckPageExists(string url)
{
//checks only the headers to be very quick
bool pageExists = false;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Http.Head;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
pageExists = response.StatusCode == HttpStatusCode.OK;
}
catch
{
return false;
}
return pageExists;
}
就这么叫吧CheckPageExists("https://www.google.com")
引用using System.Net;
这原来是一个 DNS 问题。文件中的某些服务器主机未包含在负载均衡器的主机文件中。终于修好了!
我有一个简单的健康检查系统,它向内部 URL 发送一个简单的 HTTP GET 请求,这是一个需要身份验证的 MVC 网络应用程序。例如,如果您向 https://{{IPAddress}}/MyMvcApp
发送获取请求,应用会将您重定向到 https://{{LB Host}}/MyMvcAppAuth
.
private static void UsingHttpGetRequest(string uri, Action<HttpWebResponse> action)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback
(
delegate { return true; }
);
Log("Sending the HTTP Get request...");
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Log($"Got a response! Status: {response.StatusCode}");
action(response);
}
}
我的服务器场中有两台服务器。这段代码在其中一台服务器上运行时,运行正常,但是另一台服务器出现了这个问题:
Exception: System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
- 我比较了服务器之间的 IIS 配置设置,发现没有明显差异。
- 我比较了注册表项,发现两台服务器都没有注册表项“SchUseStrongCrypto”,但两台服务器上肯定都启用了 TLS 1.2。
- 已验证两者都安装了 .NET v4.0.30319。
我对此思考得越多,就越得出这样的结论:F5 负载平衡器拒绝来自场中其中一台服务器的请求的 302 重定向。你们有什么感想?拒绝这些请求的负载平衡器可能存在 firewall/misconfiguration 问题?
另一种方法。
public static bool CheckPageExists(string url)
{
//checks only the headers to be very quick
bool pageExists = false;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Http.Head;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
pageExists = response.StatusCode == HttpStatusCode.OK;
}
catch
{
return false;
}
return pageExists;
}
就这么叫吧CheckPageExists("https://www.google.com")
引用using System.Net;
这原来是一个 DNS 问题。文件中的某些服务器主机未包含在负载均衡器的主机文件中。终于修好了!