8

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

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

它闻起来像是某种回收的连接问题,因为如果我只是重新启动看门狗应用程序,它就可以正常工作,并且响应开始以正常延迟返回。

我试过设置 request.KeepAlive = false 和 request.ServicePoint.ConnectionLimit = 1,这些都没有帮助。

另一个线索,我无法通过 IIS 管理器连接到托管在此服务器上的两个不同网站中的任何一个,这一直运行良好。我正在尝试通过 IIS 管理器连接“底层连接已关闭”。每次。我已经有一段时间没有更新任何一个网站了,所以这对我没有任何改变。

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

此外,如果我将看门狗应用程序中的 sleeptime 变量更改为 30 秒,则问题不会出现。在我相信 10-20 秒的范围内有一些神奇的数字,如果请求暂停的时间超过这个时间,它们永远不会失败。

我认为 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);
        }
    }
}
4

1 回答 1

5

你可能有悬空连接,在 HTTP 1.1 中你被限制为 2 个连接。

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

request.ProtocolVersion = HttpVersion.Version10;

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

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

如果上述任何一个解决了问题,我建议在您的请求代码周围添加一个 try...catch...finally 块,以确保每个请求都正确关闭和处理(尝试request = null在您的 finally 语句中设置方法)。

于 2013-07-08T06:02:48.707 回答