Я разработал приложение .net 3.5, которое использует HTTPWebRequest для извлечения данных с веб-сервера поставщика, после чего возвращается документ XML. На моей собственной рабочей станции xp (32bit) она работает очень быстро.
На сервере это намного медленнее. Ответ от 16 Кб от поставщика в лучшем случае занимает 20-30 секунд, тогда как на моем ПК это занимает 1 секунду.
Сервер - это виртуальная машина, работающая под управлением Windows Server 2008 в 64-битном режиме на ESX. У меня установлен Internet Explorer на сервере и я делаю тот же запрос в IE, в отличие от моего приложения, страница загружается в то же время, что и на моей рабочей станции.
Код выглядит следующим образом:
private static XElement FetchXml(string uri)
{
int retryInterval = 500;
for (int retry = 1; retry < RETRY_MAX; ++retry)
{
Stopwatch stopWatch = Stopwatch.StartNew();
try
{
var request = HttpWebRequest.Create(uri);
request.Proxy = new WebProxy("<the corporate proxy>", 8080);
// 3 minute timeout on individual web requests
request.Timeout = 1000 * 60 * 3;
using (var response = request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
XElement xml = XElement.Load(reader);
//log.InfoFormat("Fetched (Uri={0}, Size={1} bytes, Elapsed={2:N2}s).", uri, xml.ToString().Length, stopWatch.Elapsed.TotalSeconds);
return xml;
}
}
}
}
catch (Exception ex)
{
//log.ErrorFormat("Error fetching Xml (Uri={0}) : {1}", uri, ex.Message);
}
//log.InfoFormat("Retrying fetch after interval (Attempt#={0}, Interval={1}s)",
// retry, (double)retryInterval/1000);
System.Threading.Thread.Sleep(retryInterval);
// Back off for next retry if it occurs.
retryInterval *= 2;
}
string msg = String.Format("Error fetching Xml - exhausted maximum retries (Uri={0}, MaxRetries={1}).",
uri,
RETRY_MAX);
throw new ApplicationException(msg);
}
Я проверил все нижеперечисленное, потратив вчера на изучение проблемы:
ServicePointManager.CheckCertificateRevocationList = false;
ServicePointManager.DefaultConnectionLimit = 65000;
ServicePointManager.Expect100Continue = false;
Ничего из этого не помогло. Я также видел, что это говорит о том, что прокси может вызвать эти проблемы и может быть обойден, к сожалению, не в этой среде, и я не думаю, что это может быть ошибка прокси, поскольку я использую ту же самую на своей рабочей станции.
Я также получил несколько следов Microsoft Network Monitor и, что интересно, размер пакета на сервере, приходящем с удаленного сайта в мое приложение, намного меньше. На моей рабочей станции они составляют около 1400 байтов, тогда как на сервере они больше похожи на 300 байтов, и хотя я не слишком знаком с TCP, кажется, что есть много болтовни о получении http-продолжений для создания полного сообщения. Так что если на моей рабочей станции около 4 входящих сообщений для общей полезной нагрузки с 3 исходящими, то на сервере это 19 входящих сообщений с аналогичным количеством исходящих. Это, вероятно, объясняет проблему производительности, но я не понимаю, почему это происходит. Когда я загружаю страницу в IE на сервер, появляется небольшое количество запросов с большими размерами пакетов.
Сетевой монитор на моей рабочей станции XP:
HTTP:Request, GET http://xml.vendor.com/datapage/, Query:version=6.0
HTTP:Response, HTTP/1.1, Status: Ok, URL: http://xml.vendor.com/datapage/
HTTP:HTTP Payload, URL: http://xml.vendor.com/datapage/
TCP:Flags=...A...., SrcPort=2192, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3206279401, Ack=33242842, Win=64512 (scale factor 0x0) = 64512
TCP:[Continuation to #915]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=2192, PayloadLen=1360, Seq=33242842 - 33244202, Ack=3206279401, Win=65535 (scale factor 0x0) = 65535
TCP:[Continuation to #915]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=2192, PayloadLen=1360, Seq=33244202 - 33245562, Ack=3206279401, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=2192, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3206279401, Ack=33245562, Win=64512 (scale factor 0x0) = 64512
TCP:[Continuation to #915]Flags=...AP..., SrcPort=HTTP Alternate(8080), DstPort=2192, PayloadLen=557, Seq=33245562 - 33246119, Ack=3206279401, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=2192, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3206279401, Ack=33246119, Win=63955 (scale factor 0x0) = 63955
Тот же код + запрос на сервере:
HTTP:Request, GET http://xml.vendor.com/datapage/, Query:version=6.0
HTTP:Response, HTTP/1.1, Status: Ok, URL: http://xml.vendor.com/datapage/
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24013122, Win=255 (scale factor 0x8) = 65280
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=255, Seq=24013122 - 24013377, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24013377, Win=254 (scale factor 0x8) = 65024
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=254, Seq=24013377 - 24013631, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24013631, Win=253 (scale factor 0x8) = 64768
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=253, Seq=24013631 - 24013884, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24013884, Win=252 (scale factor 0x8) = 64512
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=252, Seq=24013884 - 24014136, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24014136, Win=251 (scale factor 0x8) = 64256
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=251, Seq=24014136 - 24014387, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24014387, Win=256 (scale factor 0x8) = 65536
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=256, Seq=24014387 - 24014643, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24014643, Win=255 (scale factor 0x8) = 65280
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=255, Seq=24014643 - 24014898, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24014898, Win=254 (scale factor 0x8) = 65024
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=254, Seq=24014898 - 24015152, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24015152, Win=253 (scale factor 0x8) = 64768
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=253, Seq=24015152 - 24015405, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24015405, Win=252 (scale factor 0x8) = 64512
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=252, Seq=24015405 - 24015657, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24015657, Win=251 (scale factor 0x8) = 64256
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=251, Seq=24015657 - 24015908, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24015908, Win=256 (scale factor 0x8) = 65536
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=256, Seq=24015908 - 24016164, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24016164, Win=255 (scale factor 0x8) = 65280
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=255, Seq=24016164 - 24016419, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24016419, Win=254 (scale factor 0x8) = 65024
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=254, Seq=24016419 - 24016673, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24016673, Win=253 (scale factor 0x8) = 64768
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=253, Seq=24016673 - 24016926, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24016926, Win=252 (scale factor 0x8) = 64512
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=252, Seq=24016926 - 24017178, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24017178, Win=251 (scale factor 0x8) = 64256
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=251, Seq=24017178 - 24017429, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24017429, Win=256 (scale factor 0x8) = 65536
TCP:[Continuation to #192]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=256, Seq=24017429 - 24017685, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24017685, Win=255 (scale factor 0x8) = 65280
TCP:[Continuation to #192]Flags=...AP..., SrcPort=HTTP Alternate(8080), DstPort=58401, PayloadLen=181, Seq=24017685 - 24017866, Ack=3779234716, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=58401, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=3779234716, Ack=24017866, Win=254 (scale factor 0x8) = 65024
IE на сервере выбирает ту же страницу:
HTTP:Request, GET http://xml.vendor.com/datapage/, Query:version=6.0
TCP:Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=53132, PayloadLen=0, Seq=20851875, Ack=2273238303, Win=65535 (scale factor 0x0) = 65535
HTTP:Response, HTTP/1.1, Status: Ok, URL: http://xml.vendor.com/datapage/
HTTP:HTTP Payload, URL: http://xml.vendor.com/datapage/
TCP:[Continuation to #345]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=53132, PayloadLen=1360, Seq=20853598 - 20854958, Ack=2273238303, Win=65535 (scale factor 0x0) = 65535
TCP:[Continuation to #345]Flags=...A...., SrcPort=HTTP Alternate(8080), DstPort=53132, PayloadLen=1360, Seq=20854958 - 20856318, Ack=2273238303, Win=65535 (scale factor 0x0) = 65535
TCP:[Continuation to #345]Flags=...AP..., SrcPort=HTTP Alternate(8080), DstPort=53132, PayloadLen=557, Seq=20856318 - 20856875, Ack=2273238303, Win=65535 (scale factor 0x0) = 65535
TCP:Flags=...A...., SrcPort=53132, DstPort=HTTP Alternate(8080), PayloadLen=0, Seq=2273238303, Ack=20856875, Win=16425 (scale factor 0x2) = 65700
Один интересный момент заключается в том, что при медленном запросе трассировка никогда не захватывает «полезную нагрузку HTTP». там происходит что-то странное? Как только запрос окончательно завершается на сервере, данные все еще хорошо сформированы, несмотря на это.