8

ホストされているaspx Webサイト(アプリではない)のウォッチドッグとして機能する単純なテストアプリ(Visual Studioコンソールアプリケーション)で、単純なhttpリクエストを送信して応答時間を計ることで、奇妙な散発的な問題が発生しています。私はこれを過去何週間も使用してきましたが、この特定の問題はありませんでした。日中の一見ランダムな時間に、http リクエストが上記のエラーで失敗し始めます。失敗したリクエストはすべて 60 秒かかるため、タイムアウトのように見えます。上記の一貫したエラーの期間 (あるケースでは数分から 90 分のランダムな期間) の後、エラーは停止し、http 応答は通常の速度 (通常は約 0.25 秒) でエラーなしで返され始めます。ウォッチドッグ クライアントの要求は、非常に単純なデータベース ルックアップをトリガーします。サーバー側のコードはわずか 1 ~ 2 行です。

ホスト サイトの任意の .cs ファイルを更新することで、この動作を自由にトリガーすることもできます。これにより、とりわけ、アプリ プールがリサイクルされます。すぐに、ウォッチドッグ アプリが上記のエラーで再びタイムアウトし始めます。

ウォッチドッグアプリを再起動するだけで正常に動作し、通常の遅延で応答が返ってくるため、ある種の再利用された接続の問題のようなにおいがします。

request.KeepAlive = false と request.ServicePoint.ConnectionLimit = 1 を設定しようとしましたが、役に立ちませんでした。

別の手がかりとして、IIS マネージャーを使用して、このサーバーでホストされている 2 つの異なる Web サイトのいずれにも接続できません。これは常に正常に機能していました。IIS マネージャー経由で接続しようとすると、「基になる接続が閉じられました」というメッセージが表示されます。毎回。どちらのサイトもしばらく更新していなかったので、私の変更ではありませんでした。

これは、IIS7 で実行されているバックエンドの asp.net 4 Web サイトで、統合パイプライン モードの専用アプリ プールを備えています。

また、watchdog アプリの 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