我目前在诊断一些 BasicHttpBinding/ServiceReference 性能问题时遇到了一些困难。在某些情况下,当使用Stopwatch
对服务的同步方法调用计时时,它被测量为 2.5 秒。我已经对同一调用进行了 Wireshark (pcap) 和 Fiddler (INET Web 代理) 分析,并获得了 400 毫秒的响应时间,这与最佳情况相距不远。
那么这个 2 秒的差异是从哪里来的呢?
我正在使用以下内容BasicHttpBinding
:
BasicHttpBinding httpBinding = new BasicHttpBinding
{
SendTimeout = TimeSpan.FromSeconds(_settings.SendTimeout),
ReceiveTimeout = TimeSpan.FromSeconds(_settings.SendTimeout),
MaxReceivedMessageSize = 1024 * 1024 * 100,
Security =
{
Mode = BasicHttpSecurityMode.TransportCredentialOnly,
Message = { ClientCredentialType = BasicHttpMessageCredentialType.UserName },
Transport = { ClientCredentialType = HttpClientCredentialType.Basic }
}
};
我们正在使用这些值:
ServicePointManager.Expect100Continue = false;
ServicePointManager.DefaultConnectionLimit = 20;
ServicePointManager.MaxServicePointIdleTime = 10000;
以及压缩的 HttpWebRequests:
public class CompressibleHttpRequestCreator : IWebRequestCreate
{
WebRequest IWebRequestCreate.Create(Uri uri)
{
HttpWebRequest httpWebRequest = Activator.CreateInstance(typeof(HttpWebRequest),
BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { uri, null },
null) as HttpWebRequest;
if (httpWebRequest != null)
{
httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate;
}
return httpWebRequest;
}
}
我不知道这个额外的 2 秒可能会出现在哪里 - 当我建议请求或响应在某个地方排队时会延迟请求但不确定这可能在哪里?
这些请求是 UI/用户驱动的,我们通常只有 1-5 个请求同时进行,所以ServicePointManager.DefaultConnectionLimit
20 个应该足够了。这在有和没有 Fiddler 的情况下都会发生,所以我已经消除了任何代理重用连接等 - 加上建立新的服务器连接不需要 2 秒,可以吗?
更新:
经过更多诊断后,我在输出 ServiceModel 跟踪时间时发现了一些有趣的时序。
从顶部突出显示到底部的时间是这些 TraceIdentifiers:
- http://msdn.microsoft.com/en-GB/library/System.ServiceModel.MessageWritten.aspx(写了一条消息)
- http://msdn.microsoft.com/en-GB/library/System.ServiceModel.Channels.MessageSent.aspx(通过频道发送消息)
- http://msdn.microsoft.com/en-GB/library/System.ServiceModel.Channels.HttpResponseReceived.aspx(收到 HTTP 响应)
我无法解释为什么 1 到 2 之间的持续时间可能需要 2 秒以上。有任何想法吗?线程是否有可能被取消调度或其他什么?