HttpWebRequest и занятые порты
От: Unforgiver Россия  
Дата: 22.10.08 11:10
Оценка:
Привет всем.

Есть задача — имитировать нагрузку на Web-сервер. Для этого пользуюсь классами HttpWebRequst и HttpWebResponse.

Отдельные бизнес-процессы выполняются на ура (каждый БП состоит из 10-20 запросов).
Однако при работе под нагрузкой (порядка 80-100 потоков) приложение минут через 10-15 стало отваливаться с сообщением о том, что закончились свободные порты. Поискал на MSDN — есть совет увеличить кол-во портов (по дефолту это кол-во = 5000, максимум 65000).

Но это не решение проблемы, а продление агонии

Проверил тоже самое через браузер (ИЕ) и оказалось, что там сколько не открывай одну и ту же страницу, задействованы 1-2 порта.
Как мне заставить каждый поток в приложении выполнять все свои запросы через 1 (2) порт(а), а не каждый запрос через отдельный порт ?

При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re: HttpWebRequest и занятые порты
От: Pavel M. Россия  
Дата: 22.10.08 21:55
Оценка: 2 (1)
Здравствуйте, Unforgiver, Вы писали:

U>Привет всем.


U>Проверил тоже самое через браузер (ИЕ) и оказалось, что там сколько не открывай одну и ту же страницу, задействованы 1-2 порта.

U>Как мне заставить каждый поток в приложении выполнять все свои запросы через 1 (2) порт(а), а не каждый запрос через отдельный порт ?

U>При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).


Код, пожалуйста.

Про это не забыли HttpWebRequest.Dispose???

IE использует что-то вроде SocketPool, потому что у них наверняка реализация работы с raw-sockets, так что это Вам не подоходит)
--------------------------
less think — do more
Re: HttpWebRequest и занятые порты
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.10.08 05:50
Оценка: 1 (1)
Здравствуйте, Unforgiver, Вы писали:

U>Привет всем.


U>Есть задача — имитировать нагрузку на Web-сервер. Для этого пользуюсь классами HttpWebRequst и HttpWebResponse.

Я бы на твоем месте воспользовался Load-тестами в Visual Studio.
Они позволяют гораздо быстрее сымитировать нагрузку на WebServer, причем очень реально.
Включая поведение браузера, учет кэширования, имитацию postbackов и authorization.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: HttpWebRequest и занятые порты
От: Unforgiver Россия  
Дата: 23.10.08 07:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Unforgiver, Вы писали:


U>>Привет всем.


U>>Есть задача — имитировать нагрузку на Web-сервер. Для этого пользуюсь классами HttpWebRequst и HttpWebResponse.

S>Я бы на твоем месте воспользовался Load-тестами в Visual Studio.
S>Они позволяют гораздо быстрее сымитировать нагрузку на WebServer, причем очень реально.
S>Включая поведение браузера, учет кэширования, имитацию postbackов и authorization.

Пытались, не получилось. Или не смогли что-то настроить, но записанные Студией обращения отличались от тех же обращений, записанных FIDDLERом или ACT. Их попросту было меньше.

Есть еще ЛоадРаннер, и куча других приложений.
Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re[2]: HttpWebRequest и занятые порты
От: Unforgiver Россия  
Дата: 23.10.08 07:24
Оценка:
Здравствуйте, 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, так что это Вам не подоходит)

Спасибо.
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re[3]: HttpWebRequest и занятые порты
От: Pavel M. Россия  
Дата: 23.10.08 07:28
Оценка:
Здравствуйте, Unforgiver, Вы писали:

U>Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.


При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).


Это время при использовании using, ну, или ручного вызова Dispose? Как Вы меряли? Код запостите.

http://rsdn.ru/forum/message/3148337.1.aspx
Автор: Pavel M.
Дата: 23.10.08


Если Вы не вызывали Dispose (и не использовали using), то вполне естественно, что сокет закрывается не сразу. Есть подозрения что как раз в Dispose происходит закрытие сокета и чистка буферов. Поэтому и спрашиваю.
--------------------------
less think — do more
Re[3]: HttpWebRequest и занятые порты
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.10.08 07:35
Оценка: 2 (1)
Здравствуйте, Unforgiver, Вы писали:
U>Пытались, не получилось. Или не смогли что-то настроить, но записанные Студией обращения отличались от тех же обращений, записанных FIDDLERом или ACT. Их попросту было меньше.
Ребята, это как-то даже смешно. Да, у студии рекордер не идеальный. Но ведь там же можно описывать все реквесты руками!
Что вам помешало? Это куда как проще, чем изобразить все реквесты руками на низком уровне.

U>Есть еще ЛоадРаннер, и куча других приложений.

U>Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.
1. Вы правильно диспозите реквесты и респонсы?
2. Поиграйте настройками ServicePoint, с которым работают ваши запросы. Интересный пример приведен вот здесь.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: HttpWebRequest и занятые порты
От: Unforgiver Россия  
Дата: 23.10.08 09:28
Оценка:
Здравствуйте, Pavel M., Вы писали:

PM>Здравствуйте, Unforgiver, Вы писали:


U>>Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.


PM>

PM>При вызове static-метода WebRequest.Create(...) открывается новый порт. И открываются они так гораздо быстрее, чем закрываются использованные (время закрытия я измерял, оно находится в пределах 30-40 секунд).


PM>Это время при использовании using, ну, или ручного вызова Dispose? Как Вы меряли? Код запостите.


PM>http://rsdn.ru/forum/message/3148337.1.aspx
Автор: Pavel M.
Дата: 23.10.08


PM>Если Вы не вызывали Dispose (и не использовали using), то вполне естественно, что сокет закрывается не сразу. Есть подозрения что как раз в Dispose происходит закрытие сокета и чистка буферов. Поэтому и спрашиваю.

Измерял я так:
1. Открывал cmd -> netstat — открыто Х портов.
2. Запускал 1 запрос

HttpWebRequest request = (HttpWebRequest)WebRequest.Create();
HttpWebResponse response = request.GetResponse();


3.Обновлял netstat — открыто как минимум Х + 1 портов, из которых у этого "+1" в качестве удаленной стороны значится тот сервер, к которому я подключаюсь.

4. Обновлял netstat до тех пор, пока портов не станет Х. Грубо замеряю время (п. 4 — п. 2, от того и порядок 30-40 сек). Но даже с такой точностью — это десятки секунд.

При том еще, я написал что есть совет по расширению кол-ва портов. Заодно там же есть совет "Измените значение времени, которое проходит с момента освобождения порта до момента возможности его использования в следующий раз". Не знаю, чему оно равно по дефолту, но рекомендуют — 30 сек.

Итого — 30 сек порт открыт + 30 сек его нельзя использовать = минута. За минуту откроется порядка (20 запросов * 20~30 процессов) = 400~600 портов. Это только для одной группы БП. Групп может быть несколько (реально было 2). Итого около 1К портов за минуту. Сколько-то их потом закрывается, таким образом минут 10-15 удавалось "протянуть".
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re[4]: HttpWebRequest и занятые порты
От: Unforgiver Россия  
Дата: 23.10.08 09:34
Оценка: 1 (1)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Unforgiver, Вы писали:

U>>Пытались, не получилось. Или не смогли что-то настроить, но записанные Студией обращения отличались от тех же обращений, записанных FIDDLERом или ACT. Их попросту было меньше.
S>Ребята, это как-то даже смешно. Да, у студии рекордер не идеальный. Но ведь там же можно описывать все реквесты руками!
S>Что вам помешало? Это куда как проще, чем изобразить все реквесты руками на низком уровне.
Ой ли ?
Правильнее — да. Проще — сомневаюсь. Я пробовал.
Да и потом — имитация веб-обращений это часть задачи. Кроме web тестируются еще и другие приложения. При этом однообразно задается нагрузка, однообразно пишутся логи, однообразно эти логи парсятся в дальнейшем и т.д.

U>>Есть еще ЛоадРаннер, и куча других приложений.

U>>Но задача — не выбрать инструмент, а написать то, о чем я говорил в исходном посте.
S>1. Вы правильно диспозите реквесты и респонсы?
Скорее всего нет. Уже добавил Dispose, проверить пока негде.

S>2. Поиграйте настройками ServicePoint, с которым работают ваши запросы. Интересный пример приведен вот здесь.


Спасибо, интересная ссылка. Надо покопаться
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.