“远程主机强行关闭现有连接”来自HttpWebRequest的零星错误

时间:2022-04-10 15:13:15

I'm having an odd, sporadic problem with a simple test app (Visual Studio console application) that acts as a watchdog for a hosted aspx web site (not app) by sending it simple http requests and timing the response times. I've used this for many weeks in the past without this particular problem. At seemingly random times during the day, my http requests start failing with the above error. They appear to be timeouts since the requests that fail are all taking 60 seconds. After a period of consistent errors as per above (random time periods from a few minutes to 90 minutes in one case) the errros stop and http responses start coming back with no errors at the normal speed (usually about .25s). The watchdog client requests triggers a very simple database lookup, just 1-2 lines of code on the server side. This is hosted at a shared windows hosting web host.

我有一个奇怪的,零星的问题,一个简单的测试应用程序(Visual Studio控制台应用程序),通过发送简单的http请求和计时响应时间,充当托管的aspx网站(而不是应用程序)的监视器。在过去的几个星期里,我已经使用过这个问题了。在白天看似随机的时间,我的http请求开始失败并出现上述错误。它们似乎是超时,因为失败的请求都需要60秒。在如上所述的一段时间的一致错误之后(在一种情况下从几分钟到90分钟的随机时间段),错误停止并且http响应开始返回而没有正常速度的错误(通常约0.25秒)。监视程序客户端请求触发一个非常简单的数据库查找,在服务器端只有1-2行代码。这是托管Web主机的共享窗口托管。

I can also trigger this behavior at will by updating any .cs file on my host site, which, among other things, causes the app pool to recycle. Immediately my watchdog app starts timing out again with the above error.

我还可以通过更新主机站点上的任何.cs文件来随意触发此行为,这会导致应用程序池回收。我的看门狗应用程序立即开始超时,出现上述错误。

It smells like some kind of recycled connection problem, since if I simply restart the watchdog app, it works fine and responses start coming back at the normal delay.

它闻起来像某种循环连接问题,因为如果我只是重新启动看门狗应用程序,它工作正常,响应开始在正常延迟回来。

I've tried setting request.KeepAlive = false and request.ServicePoint.ConnectionLimit = 1, those did not help.

我已经尝试过设置request.KeepAlive = false和request.ServicePoint.ConnectionLimit = 1,那些没有帮助。

Another clue, I cannot connect with IIS manager to either of two different websites hosted on this server, which has always worked fine. I'm getting "The underlying connection was closed" trying to connect via IIS Manager. Every time. I have not updated either of the sites in a while, so it wasn't any change of mine.

另一个线索,我无法将IIS管理器连接到此服务器上托管的两个不同网站中的任何一个,这一直都工作正常。我正在尝试通过IIS管理器连接“基础连接已关闭”。每次。我有一段时间没有更新任何一个网站,所以这不是我的任何改变。

This is an asp.net 4 website on the backend running on IIS7 with a dedicated app pool in integrated pipeline mode.

这是在IIS7上运行的后端的asp.net 4网站,在集成管道模式下具有专用的应用程序池。

Also if I change the sleeptime variable in the watchdog app to something like 30 seconds, the problem doesn't show up. There's some magic number in the range of I believe 10-20 seconds where if the requests are pausing more than that, they never fail.

此外,如果我将监视程序应用程序中的sleeptime变量更改为30秒,则问题不会显示出来。在我认为10-20秒的范围内有一些神奇的数字,如果请求暂停多于此,它们永远不会失败。

I think the fact that IIS Manager can't connect is good evidence that something is wrong on the host side independant of my test app but I wanted to cover my bases before opening a support incident... especially since a simple restart of my console app fixes the problem... at least for a while.

我认为IIS管理器无法连接这一事实很好地证明了我的测试应用程序独立于主机端的问题,但是我想在打开支持事件之前覆盖我的基础...特别是因为我的控制台简单重启应用程序修复问题...至少有一段时间。

class Program
{
            //make a simple web request and just return the status code
    static string SendHttpMsg(string url, string postData)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url));
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        ASCIIEncoding encoding = new ASCIIEncoding();
        byte[] byte1 = encoding.GetBytes(postData);
        request.ContentLength = byte1.Length;
        //request.KeepAlive = false; //no effect
        //request.ServicePoint.ConnectionLimit = 1; //no effect
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(byte1, 0, byte1.Length);
        requestStream.Close();
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        response.Close();
        return ((int)response.StatusCode).ToString();
    }

    static void Main(string[] args)
    {
        int sleeptime = 5000;
        string result = "";
        while (true)
        {
            DateTime start = DateTime.Now;
            try
            {
                //this is a very simple call that results in a very simple, fast query in the database
                result = SendHttpMsg("http://example.com/somepage.aspx", "command=test");
            }
            catch (Exception ex)
            {
                                //fancy exception handling here, removed
            }
            DateTime end = DateTime.Now;
            TimeSpan calltime = end - start;
            Console.WriteLine(end.ToString() + ", " + calltime.TotalSeconds.ToString("F") + " seconds " + result);
            Thread.Sleep(sleeptime);
        }
    }
}

1 个解决方案

#1


5  

You could have dangling connections, and in HTTP 1.1 you are limited to 2 connections.

您可能有悬空连接,在HTTP 1.1中,您只能连接2个。

Try changing the HTTP Protocol Version used in the request:

尝试更改请求中使用的HTTP协议版本:

request.ProtocolVersion = HttpVersion.Version10;

If that doesn't work, it could be taking a long time to resolve the proxy settings, which can be fixed by disabling the proxy settings in your application by adding the following to the .config file:

如果这不起作用,则可能需要很长时间才能解析代理设置,可以通过在.config文件中添加以下内容来禁用应用程序中的代理设置来修复代理设置:

<system.net>
  <defaultProxy enabled="false">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

If either of the above fixes the problem, I'd recommend adding a try...catch...finally block around your request code, to ensure that each request is properly closed and disposed of (try setting request = null in your finally statement inside the method).

如果上述任何一个修复了问题,我建议添加一个try ... catch ... finally阻止你的请求代码,以确保每个请求都被正确关闭并处理掉(尝试在你的finally中设置request = null方法内的声明)。

#1


5  

You could have dangling connections, and in HTTP 1.1 you are limited to 2 connections.

您可能有悬空连接,在HTTP 1.1中,您只能连接2个。

Try changing the HTTP Protocol Version used in the request:

尝试更改请求中使用的HTTP协议版本:

request.ProtocolVersion = HttpVersion.Version10;

If that doesn't work, it could be taking a long time to resolve the proxy settings, which can be fixed by disabling the proxy settings in your application by adding the following to the .config file:

如果这不起作用,则可能需要很长时间才能解析代理设置,可以通过在.config文件中添加以下内容来禁用应用程序中的代理设置来修复代理设置:

<system.net>
  <defaultProxy enabled="false">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

If either of the above fixes the problem, I'd recommend adding a try...catch...finally block around your request code, to ensure that each request is properly closed and disposed of (try setting request = null in your finally statement inside the method).

如果上述任何一个修复了问题,我建议添加一个try ... catch ... finally阻止你的请求代码,以确保每个请求都被正确关闭并处理掉(尝试在你的finally中设置request = null方法内的声明)。