Есть задача — имитировать нагрузку на Web-сервер. Для этого пользуюсь классами HttpWebRequst и HttpWebResponse.
Отдельные бизнес-процессы выполняются на ура (каждый БП состоит из 10-20 запросов).
Однако при работе под нагрузкой (порядка 80-100 потоков) приложение минут через 10-15 стало отваливаться с сообщением о том, что закончились свободные порты. Поискал на MSDN — есть совет увеличить кол-во портов (по дефолту это кол-во = 5000, максимум 65000).
Но это не решение проблемы, а продление агонии
Проверил тоже самое через браузер (ИЕ) и оказалось, что там сколько не открывай одну и ту же страницу, задействованы 1-2 порта.
Как мне заставить каждый поток в приложении выполнять все свои запросы через 1 (2) порт(а), а не каждый запрос через отдельный порт ?
При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Здравствуйте, Unforgiver, Вы писали:
U>Привет всем.
U>Проверил тоже самое через браузер (ИЕ) и оказалось, что там сколько не открывай одну и ту же страницу, задействованы 1-2 порта. U>Как мне заставить каждый поток в приложении выполнять все свои запросы через 1 (2) порт(а), а не каждый запрос через отдельный порт ?
U>При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).
Здравствуйте, Unforgiver, Вы писали:
U>Привет всем.
U>Есть задача — имитировать нагрузку на Web-сервер. Для этого пользуюсь классами HttpWebRequst и HttpWebResponse.
Я бы на твоем месте воспользовался Load-тестами в Visual Studio.
Они позволяют гораздо быстрее сымитировать нагрузку на WebServer, причем очень реально.
Включая поведение браузера, учет кэширования, имитацию postbackов и authorization.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Unforgiver, Вы писали:
U>>Привет всем.
U>>Есть задача — имитировать нагрузку на Web-сервер. Для этого пользуюсь классами HttpWebRequst и HttpWebResponse. S>Я бы на твоем месте воспользовался Load-тестами в Visual Studio. S>Они позволяют гораздо быстрее сымитировать нагрузку на WebServer, причем очень реально. S>Включая поведение браузера, учет кэширования, имитацию postbackов и authorization.
Пытались, не получилось. Или не смогли что-то настроить, но записанные Студией обращения отличались от тех же обращений, записанных FIDDLERом или ACT. Их попросту было меньше.
Есть еще ЛоадРаннер, и куча других приложений.
Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Здравствуйте, Pavel M., Вы писали:
PM>Здравствуйте, Unforgiver, Вы писали:
U>>Привет всем.
U>>Проверил тоже самое через браузер (ИЕ) и оказалось, что там сколько не открывай одну и ту же страницу, задействованы 1-2 порта. U>>Как мне заставить каждый поток в приложении выполнять все свои запросы через 1 (2) порт(а), а не каждый запрос через отдельный порт ?
U>>При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).
PM>Код, пожалуйста.
Код стандартный из примеров, адаптированный под свою задачу.
Создать WebRequest, вызвать метод GetResponseStream, получить WebResponse.
PM>Про это не забыли HttpWebRequest.Dispose???
Я использовал WebResponse.Close(). думал, что этого достаточно. Добавил Dispose, посмотрю что будет дальше.
PM>IE использует что-то вроде SocketPool, потому что у них наверняка реализация работы с raw-sockets, так что это Вам не подоходит)
Спасибо.
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Здравствуйте, Unforgiver, Вы писали:
U>Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.
При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).
Это время при использовании using, ну, или ручного вызова Dispose? Как Вы меряли? Код запостите.
Если Вы не вызывали Dispose (и не использовали using), то вполне естественно, что сокет закрывается не сразу. Есть подозрения что как раз в Dispose происходит закрытие сокета и чистка буферов. Поэтому и спрашиваю.
Здравствуйте, Unforgiver, Вы писали: U>Пытались, не получилось. Или не смогли что-то настроить, но записанные Студией обращения отличались от тех же обращений, записанных FIDDLERом или ACT. Их попросту было меньше.
Ребята, это как-то даже смешно. Да, у студии рекордер не идеальный. Но ведь там же можно описывать все реквесты руками!
Что вам помешало? Это куда как проще, чем изобразить все реквесты руками на низком уровне.
U>Есть еще ЛоадРаннер, и куча других приложений. U>Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.
1. Вы правильно диспозите реквесты и респонсы?
2. Поиграйте настройками ServicePoint, с которым работают ваши запросы. Интересный пример приведен вот здесь.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel M., Вы писали:
PM>Здравствуйте, Unforgiver, Вы писали:
U>>Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.
PM>
PM>При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).
PM>Если Вы не вызывали Dispose (и не использовали using), то вполне естественно, что сокет закрывается не сразу. Есть подозрения что как раз в Dispose происходит закрытие сокета и чистка буферов. Поэтому и спрашиваю.
Измерял я так:
1. Открывал cmd -> netstat — открыто Х портов.
2. Запускал 1 запрос
3.Обновлял netstat — открыто как минимум Х + 1 портов, из которых у этого "+1" в качестве удаленной стороны значится тот сервер, к которому я подключаюсь.
4. Обновлял netstat до тех пор, пока портов не станет Х. Грубо замеряю время (п. 4 — п. 2, от того и порядок 30-40 сек). Но даже с такой точностью — это десятки секунд.
При том еще, я написал что есть совет по расширению кол-ва портов. Заодно там же есть совет "Измените значение времени, которое проходит с момента освобождения порта до момента возможности его использования в следующий раз". Не знаю, чему оно равно по дефолту, но рекомендуют — 30 сек.
Итого — 30 сек порт открыт + 30 сек его нельзя использовать = минута. За минуту откроется порядка (20 запросов * 20~30 процессов) = 400~600 портов. Это только для одной группы БП. Групп может быть несколько (реально было 2). Итого около 1К портов за минуту. Сколько-то их потом закрывается, таким образом минут 10-15 удавалось "протянуть".
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Unforgiver, Вы писали: U>>Пытались, не получилось. Или не смогли что-то настроить, но записанные Студией обращения отличались от тех же обращений, записанных FIDDLERом или ACT. Их попросту было меньше. S>Ребята, это как-то даже смешно. Да, у студии рекордер не идеальный. Но ведь там же можно описывать все реквесты руками! S>Что вам помешало? Это куда как проще, чем изобразить все реквесты руками на низком уровне.
Ой ли ?
Правильнее — да. Проще — сомневаюсь. Я пробовал.
Да и потом — имитация веб-обращений это часть задачи. Кроме web тестируются еще и другие приложения. При этом однообразно задается нагрузка, однообразно пишутся логи, однообразно эти логи парсятся в дальнейшем и т.д.
U>>Есть еще ЛоадРаннер, и куча других приложений. U>>Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте. S>1. Вы правильно диспозите реквесты и респонсы?
Скорее всего нет. Уже добавил Dispose, проверить пока негде.
S>2. Поиграйте настройками ServicePoint, с которым работают ваши запросы. Интересный пример приведен вот здесь.
Спасибо, интересная ссылка. Надо покопаться
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.