我有以下问题:
我正在研究一个.Net模块,该模块每隔约500ms向位于与IIS服务器相同区域的服务器发送请求。
大多数这些要求(约99%)需要大约1~3ms才能得到治疗。但是,其中一些请求超时(我将WebRequest.Timeout
设置为150毫秒,这很重要。)
有两件奇怪的事情:
WebRequest.GetResponse()
和捕获异常的那一刻之间测量~350ms,而我将WebRequet.Timeout
设置为150ms。这种性能差距对我们来说确实是一个问题,我不明白为什么会发生这种情况这是我正在处理的遗留代码:
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的行为以及为什么它会像我一样经历一些重大的减速?为什么将超时设置为150毫秒会导致异常被捕获到350毫秒(这对我们来说是一个糟糕的性能问题)?
我真的很喜欢C#和.Net经验丰富的人的帮助,因为我是这个世界的新手并且有客户请求限制
提前谢谢
答案 0 :(得分:0)
问题可能与DNS查询有关。 Timeout
状态的documentation:
域名系统(DNS)查询最多可能需要15秒才能返回 或者超时。如果您的请求包含需要的主机名 分辨率,你可以将Timeout设置为小于15秒的值 在抛出WebException之前需要15秒或更长时间来指示a 你的请求超时。