私は以下の問題を抱えています。 IISサーバーと同じ地域にあるサーバーに約500msごとにリクエストを送信する.Netモジュールで作業しています。 これらの要求のほとんど(約99%)は、処理するのに約1〜3msかかる。しかし、これらの要求の一部はタイムアウトしています(私はWebRequest.Timeout
を150msに設定しました、それは重要です)。.Netモジュールの奇妙なタイムアウトの問題
2奇妙なことがあります:
- まず、タイムアウト要求が他の要求が雷
- として迅速ですと奇妙である私が無限にタイムアウトを設定した場合に実行する〜について180msを取るだろうWebExceptionをキャッチすると、を150msに設定していたのに対して、私は
WebRequest.GetResponse()
と呼び出されてから例外がキャッチされるまでの間に〜350msを測定します。パフォーマンスのこのギャップは本当に私たちのための問題であり、それはこれが私が働いているレガシーコードです
が起こっている理由を私は理解していない:
ApiResult IApiService.Request(IConnectorRequest request)
{
long timestamp = 0;
DebugStream debug = null;
try
{
var dictionary = CollectData(request);
//TODO:May be include some ServicePoint information.
//APIConnectionState=Reused
// Sending request to the API //////////////////////////////////////////////////////
var http = CreateRequest();
Stream stream;
using (stream = http.GetRequestStream())
{
if (_Log.IsDebug)
{
stream = debug = new DebugStream(stream, _Encoding);
}
dictionary.WriteForm(stream, _Encoding);
}
if (debug != null)
{
_Log.Debug("WebRequestApiService.Request({0:N}): {1}", request.Id, debug.Data);
}
// Start request and fix timestamp before execution.
timestamp = Stopwatch.GetTimestamp();
var response = http.GetResponse() as HttpWebResponse;
// (Stopwatch.GetTimestamp() - timestamp)/TimeSpan.TicksPerMillisecond => ~2ms
if (response == null)
{
const string message = "Response is not HttpWebResponse";
_Log.Warning("WebRequestApiService.Request({0:N}): {1}", request.Id, message);
return ApiResult.Failure(message);
}
response.GetRequestHeaders();
return new ApiResult()
{
StatusCode = (int)response.StatusCode,
Description = response.StatusDescription,
DataDomeStatus = response.GetStatusHeader(),
Headers = response.GetHeaders()
};
}
catch (WebException we)
{
var errorMessage = string.Empty;
var response = we.Response as HttpWebResponse;
Exception e;
if (response != null)
{
errorMessage = response.GetText(out e);
if (response.StatusCode == HttpStatusCode.Forbidden)
{
return new ApiResult()
{
StatusCode = (int)response.StatusCode,
Description = response.StatusDescription,
DataDomeStatus = response.GetStatusHeader(),
Headers = response.GetHeaders(),
Content = errorMessage
};
}
if (errorMessage == null)
{
_Log.Warning("WebRequestApiService.Request({0}): Problem getting response {1}", request.Id, e);
}
}
// (Stopwatch.GetTimestamp() - timestamp)/TimeSpan.TicksPerMillisecond => ~350ms
_Log.Warning(
"WebRequestApiService.Request({0}): Message={1}\nTimeout={2}\nError=\n{3}\n\nRequest=\n{4}\n\nAPI=\n{5}\n",
request.Id,
errorMessage,
(Stopwatch.GetTimestamp() - timestamp)/TimeSpan.TicksPerMillisecond,
we,
request.Dump(),
debug != null ? debug.Data : "NULL"
);
return ApiResult.Failure(errorMessage);
}
catch (Exception e)
{
_Log.Warning(
"WebRequestApiService.Request({0}): Timeout={1}\nError=\n{2}\n\nRequest=\n{3}\n\nAPI=\n{4}\n",
request.Id,
(Stopwatch.GetTimestamp() - timestamp)/TimeSpan.TicksPerMillisecond,
e,
request.Dump(),
debug != null ? debug.Data : "NULL"
);
return ApiResult.Failure(e.Message);
}
}
そして、これが使用される方法であります私たちは、HttpWebRequestを作成します。
private HttpWebRequest CreateRequest()
{
var http = WebRequest.Create(_uri) as HttpWebRequest;
if (http == null)
{
throw new NotImplementedException();
}
// Disable proxy (if node proxy configuration in config file). Otherwise the first
// request will be slowed down due the proxy auto-detection.
if (_noProxy)
{
http.Proxy = null;
}
// Configure timeout. 150ms in our case
http.Timeout = _timeout;
// Force connection to be keep-alive.
http.KeepAlive = true;
// Disable caching.
http.CachePolicy = _cachePolicy;
// Basic request fields
http.Method = "POST";
http.ContentType = "application/x-www-form-urlencoded";
http.UserAgent = null;
// If auto redirect is allowed, then we can't catch redirect response from API server.
http.AllowAutoRedirect = false;
return http;
}
誰かがWebRequestクラスの振る舞いを知っていて、それはいくつかの重いスローダウンを持つことができますなぜ私が経験していていますか?タイムアウトを150msに設定すると、例外が350msでキャッチされる(これはパフォーマンスの重い問題です)。
私は本当にC#と.NETでより多くの経験を積んだ人からいくつかの助けのように、私はこの世界に新たなんだと思いますので、顧客は制約が
が問題の可能性が高いDNSで、事前
DNSルックアップには関係しません。私は自分のアイデアを検証しようとしました。.NetアプリケーションからDNSルックアップのトラフィックを盗聴しました。その結果、10分間と1000リクエスト以上で4回のDNS検索が行われ、50回のタイムアウトが発生しました。また、タイムアウトの日付とDNSルックアップの日付が一致しません:( –