чем нагрузить сервер для тестирования

Top 10 лучших инструментов для нагрузочного тестирования

Нагрузочное тестирование позволяет оценить производительность программного обеспечения при различных нагрузках от действий определенного количества пользователей. Бизнесу всегда важно знать производительность программного обеспечения в реальных условиях, выявить основные уязвимости и обеспечить высокое качество ПО. Нагрузочное тестирование позволяет снизить риск сбоя после запуска приложения в реальных условиях. Однако, если Вы хотите эффективно выполнить нагрузочное тестирование, Вам понадобятся инструменты тестирования эффективности нагрузки, которые помогут смоделировать виртуальных пользователей и выполнять тестовые сценарии.

Рынок программного обеспечения сегодня полон различных инструментов нагрузочного тестирования, начиная от приложений с открытым исходным кодом и заканчивая инструментами для автоматизированного нагрузочного тестирования премиум-класса. Тем не менее, имея такое количество доступных вариантов, иногда трудно выбрать лучший инструмент нагрузочного тестирования для вашего бизнеса. В этой статье мы рассмотрим список инструментов нагрузочного тестирования и обсудим плюсы и минусы каждого из них.

Инструменты

Apache JMeter

Apache JMeter – на настоящий момент один из самых популярных инструментов с открытым исходным кодом для нагрузочного тестирования. Инструмент разрабатывается с 2003 года и за прошедшие десятилетия оброс богатой функциональностью и достаточно давно успел себя зарекомендовать, как прекрасную альтернативу платным аналогам для большинства решаемых задач.

Инструмент кроссплатформенный, так как разработан на Java. Доступна как работа из GUI, так и запуски в консольном режиме.

Apache JMeter поддерживает работу с различными сетевыми протоколами разных уровней HTTP, HTTPS, FTP, LDAP, SOAP, TCP, почтовых протоколов и shell-скриптов. Он, как java-based инструмент, предоставляет возможности по работе с JDBC, Message-oriented middleware (MOM) через JMS и Java Objects.

Для высоких нагрузок запуска одного инстанса JMeter может и не хватить, но эта проблема решаема тюнингом конфигурационных файлов инструмента или использованием распределенного запуска.

JMeter действительно очень популярен в отрасли, об этом говорит тот факт, что некоторые инструменты из нашего списка используют JMeter в качестве своего движка.

Плюсы

Минусы

Протоколы

Ценообразование

Кому подходит

Apache Jmeter – это отличный инструмент нагрузочного тестирования с открытым исходным кодом для больших и малых компаний. Программа предоставляет бесплатно своим пользователям различные полезные инструменты тестирования, и пользователи могут настроить её в соответствии со своими потребностями.

LoadRunner

Micro-Focus Loadrunner (ранее известный как HP Loadrunner) – это довольно сложный инструмент нагрузочного тестирования программного обеспечения, который обнаруживает проблемы с производительностью, наверное, прежде всего в энтерпрайз-приложениях. LoadRunner может применяться для тестирования программного обеспечения ERP, устаревших системных приложений, а также технологий Web 2.0.

Loadrunner позволяет тестировщикам ПО осуществлять комплексную оценку производительности своей системы. Он специализируется на выявлении узких мест до того, как приложение будет внедрено или до стадии развертывания. В результате пользователи могут оценить каждый компонент по отдельности, прежде чем он начнет работать.

LoadRunner чрезвычайно полезен при обнаружении пробелов в производительности, если предвидится обновление системы. Также он предоставляет пользователям продвинутые функции для прогнозирования затрат по увеличению производительности приложений. Благодаря точному прогнозированию таких затрат, связанных с аппаратным и программным обеспечением, специалистам проще повысить производительность и масштабируемость Вашего приложения.

Плюсы

Минусы

Ценообразование

Протоколы

Кому подходит

Micro Focus LoadRunner – это достаточно сложный и универсальный инструмент для нагрузочного тестирования, подходящий для тестирования различных платформ. Однако из-за своей цены этот инструмент больше подходит для средних и крупных организаций.

Load Ninja

Load Ninja – это относительно несложный в использовании инструмент нагрузочного тестирования, который позволяет пользователям создавать сложные нагрузочные тесты без использования каких-либо скриптов. В результате пользователи могут сократить время тестирования на 50% и заменить эмуляторы нагрузки реальными браузерами.

Этот инструмент средствами браузера собирает метрики, которые позволяют оценить производительность вашего приложения. В то же время вы можете выполнять отладку в режиме реального времени, выявлять проблемы с производительностью и быстро фиксировать взаимодействие на стороне клиента.

Load Ninja также позволяет командам расширить охват своих тестов независимо от качества программного обеспечения. Это помогает пользователю свести к минимуму сложные и трудоемкие процедуры, такие как написание и отладка скрипта или динамическая корреляция. С помощью этого инструмента тестировщикам больше не нужно тратить много времени на создание тестовых сценариев, а можно уделить больше времени созданию масштабируемых приложений.

Плюсы

Минусы

Протоколы

Ценообразование

Кому подходит

Load Ninja – это отличный инструмент тестирования программного обеспечения для веб-разработчиков и тестировщиков ПО, которые хотят реализовать процедуры тестирования без скриптов. Однако из-за цены наиболее подходит для среднего и крупного бизнеса.

WebLOAD

WebLOAD – это инструмент корпоративного нагрузочного тестирования, который позволяет пользователям создавать надежные, реальные сценарии нагрузки. Это надежный инструмент тестирования, который работает для сложных систем и предоставляет пользователям расширенные функции, такие как анализ производительности и интеллектуальная аналитика. В то же время, инструмент основан на гибкой платформе, которая предлагает встроенную поддержку нескольких технологий, а также интеграцию с рядом инструментов, начиная от мониторинга производительности до конвейеров CI/CD.

Плюсы

Минусы

Протоколы

Ценообразование

Кому подходит

WebLOAD – это комплексный инструмент для нагрузочного тестирования, который позволяет компаниям любого размера тестировать веб-сайты, обычные и корпоративные приложения.

LoadUI Pro

LoadUI – это особенный инструмент для нагрузочного тестирования. В основном предназначен для веб-сервисов, работающих на Linux, Windows и Mac OS, и позволяет пользователям оценивать масштабируемость, скорость и производительность API. В результате пользователи могут просмотреть поведение производительности API, и уже после внедрять ПО в продуктив.

С помощью этого инструмента пользователи могут проверить, может ли API справляться с нагрузкой из облака. В то же время вы можете использовать существующие тесты SoapUI Pro и использовать их в различных сценариях нагрузочных тестов, не изменяя исходных тестов.

LoadUI Pro также позволяет пользователям запускать несколько сценариев нагрузочного тестирования одновременно. Это позволяет пользователям оценить, как различные условия тестирования взаимодействуют друг с другом и влияют на производительность API.

Плюсы

Минусы

Протоколы

Ценообразование

Кому подходит

LoadUI Pro отлично подходит для разработчиков ПО и ИТ-специалистов. LoadUI Pro предлагает облачное и локальное программное обеспечение API. Вы можете использовать этот инструмент автоматизации нагрузочного тестирования для создания, управления и выполнения нагрузочных тестов баз данных, микросервисов и API REST & SOAP.

BlazeMeter

BlazeMeter – компания-производитель одноимённого программного обеспечения для тестирования, предоставляющая пользователям тестирование производительности и нагрузочное тестирование как услугу. Служба содержит инновационную и всеобъемлющую платформу непрерывного тестирования. Веб-интерфейс приложения эффективен для создания статических нагрузочных тестов и использования сценариев JMeter для выполнения динамических нагрузочных тестов.

BlazeMeter известен широчайшим использованием одного из лучших инструментов нагрузочного тестирования с открытым исходным кодом – Apache Jmeter. Он предоставляет различные корпоративные функции для бесплатной платформы. То есть пользователи могут получить доступ ко многим расширенным функциям, таким как мониторинг производительности приложений (APM), создание отчетов в режиме реального времени, распределенное тестирование и интеграция с инструментами разработчика для непрерывной интеграции (CI).

Плюсы

Минусы

Ценообразование (годовые планы)

Кому подходит

BlazeMeter – отличный инструмент для нагрузочного тестирования для организаций, которые уже используют Apache Jmeter.

K6

K6 – набирающий популярность современный инструмент для нагрузочного тестирования с открытым исходным кодом, предназначенный прежде всего для разработчиков.

K6 написан разработчиками другого нагрузочного инструмента – loadimpact и служит прежде всего для проверки производительности сайтов. Backend инструмента написан на языке Go, а сами скрипты пишутся на JavaScript.

Некоторые тезисы идеологов данного инструмента могут вызывать споры между разными представителями IT-отрасли, хотя прежде всего они сообщают нам о целевой аудитории использования данного инструмента. В общем, если бюджет на тестирование мал, а тестировать всё равно нужно, то нагрузочное тестирование может провести разработчик самостоятельно, ведь лучше провести хотя бы упрощённое тестирование, чем вообще не иметь никакого.

Запуск тестов происходит в консольном режиме, результаты тестирования по умолчанию также выводятся в консоль, однако доступна поддержка таких плагинов для вывода результатов, как Kafka, Datadog, InfluxDB, JSON и StatsD.

K6 имеет не только версию с открытым исходным кодом, но и платную облачную версию с дополнительной функциональностью и масштабированием нагрузки.

Плюсы

Минусы

Ценообразование

Протоколы

Кому подходит

Разработчикам, которые интересуются тестированием и хотят писать высокопроизводительный код, а также компаниям, по тем или иным причинам не имеют возможность организовать независимое тестирование.

Яндекс.Танк

Не секрет, что в компании Яндекс имеется своя экосистема различных инструментов для абсолютно разных задач. Некоторые говорят, что если есть возможность написать свой инструмент, то Яндекс обязательно это сделает (иногда без оглядки на уже имеющиеся решения). Не обошла стороной эта тема и инструменты для нагрузочного тестирования.

После своего создания в 2006 году, Танк прошёл длинный путь своего развития и сейчас позволяет использовать разные типы генераторов нагрузки. Если нужно протестировать http-сервис на высокую нагрузку, то используется Phantom (C++). Интеграция Танка с JMeter в свою очередь позволяет реализовать сценарный тип тестирования со всеми протоколами, которые поддерживаются JMeter.

Кроме того, можно использовать BFG-Python-генератор и написанный на Go Pandora.

Сам Танк реализован на Python и может использоваться только в Unix-системах.

Плюсы

Минусы

Ценообразование

Протоколы

Кому подходит

Яндекс.Танк хорошо подходит в сочетании с phantom, если отсутствует необходимость в сценарном тестировании и требуется высокая производительность.

Gatling

Gatling – это ещё один популярный инструмент для проведения нагрузочного тестирования с открытым исходным кодом. Он написан на языке Scala с использованием технологий Netty и Akka.

Если Вы – разработчик, знакомый со Scala и Вам нужно провести нагрузочное тестирование, то Gatling – идеально вам подойдёт.

Скрипты на gatling пишутся в привычной среде разработки, и поддерживают инструменты автоматизации сборки sbt и maven. Также реализована возможность встраивания в процессы непрерывной интеграции с помощью Jenkins.

Удобство gatling для разработчика также состоит в том, что по завершении тестирования отчёт создаётся автоматически, его остаётся только проанализировать.

Что касается поддержки протоколов, то согласно официальной документации поддерживаются HTTP(s)/1, websocket, JMS, MQTT. Протокол HTTP 2.0 имеет ограниченную поддержку.

Плюсы

Минусы

Протоколы

Ценообразование

Кому подходит

Gatling – это хороший бесплатный инструмент нагрузочного тестирования с открытым исходным кодом, который лучше всего подойдёт для проектов, связанных с языком Scala.

Boomq.io

Boomq.io – это продукт нового поколения, который позволяет проводить тесты в облаке для любой аудитории, которая занимается нагрузочным тестированием. Маркетологи, менеджеры по продукту и руководители проектов, разработчики и инженеры – все могут использовать boomq.io для своих целей.

Для маркетологов boomq.io предоставляет простой в использовании инструмент, который интегрируется с Google Analytics и Яндекс.Метрикой для получения статистической информации и выполнения тестов производительности без какого-либо программирования или других технических разработок.

Разработчики и инженеры могут использовать boomq.io для удобного проведения тестов производительности в облаке. У них появляется полный набор инструментов тестирования (работающих в облаке в качестве службы SaaS), таких как импорт HAR/Insomnia, определение запросов, параметризация и корреляция.

У boomq.io есть удобный анализ результатов повторяющихся онлайн тестов с помощью графических панелей. В целом, boomq.io представляет новое поколение продуктов для тестирования производительности, которое позволяет легко создавать, планировать, запускать и выполнять тесты в облаке, используя простой и понятный веб-интерфейс.

Плюсы

Минусы

Протоколы

Ценообразование

Boomq – это облачное решение по подписке, где Вы платите только за то, что потребляете, с ценой от 15 долларов в месяц, все операции с продуктом включены в стоимость подписки.

Кому подходит

Вы тестируете сайт, API или приложение? Используйте boomq.io и максимально ускоряйте циклы тестирования. Если у Вас нет опыта в тестировании производительности – boomq.io – это Ваш лучший выбор.

Вывод

Когда речь идет о лучшем инструменте для нагрузочного тестирования программного обеспечения, то пока нет единственного решения, подходящего для абсолютно всех ситуаций. Если Вы хотите найти лучший инструмент для нагрузочного тестирования производительности для Вашей компании, внимательно изучите каждый вариант и выберите тот, который лучше всего соответствует Вашим потребностям и целям.

Источник

Быстрое создание нагрузочных тестов на JMeter для web-сайтов

чем нагрузить сервер для тестирования. 44e02f7b075782942f1729eed3c0bc9e. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-44e02f7b075782942f1729eed3c0bc9e. картинка чем нагрузить сервер для тестирования. картинка 44e02f7b075782942f1729eed3c0bc9e.Для любого программного приложения, предназначенного для массового обслуживания пользователей, необходимо проводить нагрузочное тестирование на предмет его надежности и отказоустойчивости. А так как любой web-сайт — это по своей сути система массового обслуживания, то проверка его на отказоустойчивость всегда является неотъемлемой частью разработки. Существуют различные решения для проведения нагрузочного тестирования веб-приложений. Я не буду сейчас описывать их подробно, про некоторые из них есть упоминания здесь.

В этой статье я хочу поделиться своим опытом использования такого средства, как Apache JMeter. После того как мною были перепробовано с десяток различных подобных инструментом, в итоге я остановился именно на JMeter, так как его возможности с лихвой охватывали мои цели и задачи. И при этом данное программное средство весьма быстрое и легковесное.

Для тех кто ни разу не использовал JMeter, рекомендую для начала почитать базовые обзоры, например, Простой нагрузочный тест с Apache JMeter. Когда я первый раз запустил данную программу, первая мысль была разобраться во всем методом «тыка», но как выяснилось это вообще нереально, и метод «тыка» неприменим к JMeter. Поэтому если хотите его использовать, то сразу открывайте мануал, поверьте, вам придется заглядывать туда очень часто, пока полностью не разберетесь, что и как. Я же здесь сейчас опишу самое очевидное и важное, а именно: как собственно создавать нагрузочные тесты. Если бы я в свое время сразу нашел подобную статью, то сэкономил бы без малого день на изучении этой софтины.

Итак, поехали! Для интереса представим, что у нас не просто сайт, а серьезное веб-приложение с авторизацией, различными пост-запросами и т.д.

1. Запускаем JMeter.

2. Создаем Thread group:

чем нагрузить сервер для тестирования. 5bbd8efeef43491b2fec534eed585a85. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-5bbd8efeef43491b2fec534eed585a85. картинка чем нагрузить сервер для тестирования. картинка 5bbd8efeef43491b2fec534eed585a85.

чем нагрузить сервер для тестирования. b56e70d18dda9489ee6fc725b2a580fb. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-b56e70d18dda9489ee6fc725b2a580fb. картинка чем нагрузить сервер для тестирования. картинка b56e70d18dda9489ee6fc725b2a580fb.

В соответствующие поля устанавливаем адрес сайта, порт (если нужно), путь к странице. Например, так:

чем нагрузить сервер для тестирования. 5697d2a7c592fa1375d9427189fe5ef2. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-5697d2a7c592fa1375d9427189fe5ef2. картинка чем нагрузить сервер для тестирования. картинка 5697d2a7c592fa1375d9427189fe5ef2.

Кроме того можно добавить параметры для запросов. И такой способ создания сценариев теста вполне приемлем для несложных сайтов. Однако в нашем случае прописывать параметры запросов для авторизации может быть утомительным занятием. Кроме того, есть нужно создать последовательность действий для обхода сайта, скажем, хотя бы по 15-ти страницам, то опять же такой вариант уже не подходит. Конечно же ручной труд не для нас, и по-хорошему это дело нужно автоматизировать. В JMeter есть такая возможность, называется запись тестов через проксирование. Т.е. мы будем выполнять любые действия через браузер, и при этом все необходимые элементы HTTP Request будут создаваться без нашего участия. Смотрим далее по пунктам, как это делается.

чем нагрузить сервер для тестирования. 2b6261c92fb513bc039c16219152bb17. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-2b6261c92fb513bc039c16219152bb17. картинка чем нагрузить сервер для тестирования. картинка 2b6261c92fb513bc039c16219152bb17.

чем нагрузить сервер для тестирования. 53739318d1e44ffb32ed1670a7443594. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-53739318d1e44ffb32ed1670a7443594. картинка чем нагрузить сервер для тестирования. картинка 53739318d1e44ffb32ed1670a7443594.

По сути здесь достаточно только изменить номер порта прокси-сервера, если порт по умолчанию 8080 у вас уже занят, например, можно поставить 8089. Если оставить в графе Target Controller значение Use Recording Controller, то все запросы, проходящие через прокси, будут записываться в первый попавшийся Recording Controller в нашем тест-плане. Но так как на данный момент он там всего один, то нас этот вариант устроит. Далее рекомендую обратить внимание на настройку фильтрации. Эти настройки предоставляют широкие возможности по фильтрации запросов. Это могут быть отдельные страницы, или например все js-скрипты и т.д. и т.п. Опять же в мануале они описаны достаточно хорошо.

6. В настройках браузера нужно указать адрес прокси и порт. Убедиться, что браузер ходит в интернет именно через нее, для этого перейти на любой сайт в интернете, при этом страница не должна загрузиться. Далее нам осталось в окне с настройками HTTP Proxy Server нажать на кнопку Start, запустив тем самым нашу проксю. После этого через браузер, открываем страницу тестируемого сайта, логинимся, выполняем различные действия, посещаем разных страницы, при этом сценарий уже начнет сохраняться в элемент Recording Controller. Когда вы поймете, что записанный вами сценарий уже достаточно суровый, для того чтобы задать вашему сайту жару, останавливаете прокси.
Получили, примерно, следующую картину:

чем нагрузить сервер для тестирования. 0fc2427c3c2f6d6a7ab80f1a96481d84. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-0fc2427c3c2f6d6a7ab80f1a96481d84. картинка чем нагрузить сервер для тестирования. картинка 0fc2427c3c2f6d6a7ab80f1a96481d84.

Названия элементов могут оказаться мало о чем говорящими. Поэтому чтобы в дальнейшем было просто наблюдать за ходом теста, эти элементы имеет смысл переименовать.

7. В настройках элемента Thread Group выберите количество потоков, число итераций, время прогрева. Например, я установил такие настройки:

чем нагрузить сервер для тестирования. 5a65cf5b084ea9fe8b030f66b5d56e17. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-5a65cf5b084ea9fe8b030f66b5d56e17. картинка чем нагрузить сервер для тестирования. картинка 5a65cf5b084ea9fe8b030f66b5d56e17.

Это значит, что тестирование будет проходить в 10 потоков, будет длиться бесконечно пока, его принудительно не остановят. Время прогрева я поставил 30 сек. Это значит, что потоки будут равномерно стартовать в течении 30 секунд, т.е. каждые три секунды, будет запускаться новый поток.

8. Чтобы наблюдать результаты тестов, а также следить за ходом выполнения, нужно добавить несколько элементов мониторинга. Я обычно добавляю такие: View Results Tree, View Results in Table, Graph Results, Summary Report. Как и что они показывают, думаю, вы разберетесь сами. Единственно, что отмечу, очень полезный элемент View Results Tree, в котором можно смотреть все параметры и содержимое запросов и ответов:

чем нагрузить сервер для тестирования. 8782a2988f25172e7d7bce065c363820. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-8782a2988f25172e7d7bce065c363820. картинка чем нагрузить сервер для тестирования. картинка 8782a2988f25172e7d7bce065c363820.

Таким образом можно проверять, что всё работает так как надо.

Вот собственно и всё! Таким образом можно создать нагрузочный тест для вашего сайта за считанные минуты.
Напоследок, скажу еще пару полезных фич, которые реализованы в Apach JMeter.

Настройки по умолчанию
Загрузка списка пользователей из файла

чем нагрузить сервер для тестирования. 1ea5b494262576b85adf11e84e63b3c6. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-1ea5b494262576b85adf11e84e63b3c6. картинка чем нагрузить сервер для тестирования. картинка 1ea5b494262576b85adf11e84e63b3c6.

В появившемся окне указываем имя, путь к файлу (если положить его рядом с файлом проекта, то достаточно указать одно имя), а также имена переменных. Эти имена вы задаете сами, они в дальнейшем будут использоваться при формировании запроса. К примеру, для связки юзер\пароль, я указал два имени переменных: USER, PASS.
Сам файл с расширением csv может выглядеть так:
userName1,pass1
userName2,pass2
userName3,pass3

чем нагрузить сервер для тестирования. e95cef9dcdf407e2a2380b4aed866528. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-e95cef9dcdf407e2a2380b4aed866528. картинка чем нагрузить сервер для тестирования. картинка e95cef9dcdf407e2a2380b4aed866528.

После этого JMeter будет циклически использовать эти креденшелы для разных потоков, обеспечивая таким образом вполне реалистичную нагрузку на сайт.

Источник

Как я решил протестировать нагрузочную способность web сервера

Это была вступительная минутка юмора, а если серьёзно то вопрос о тестировании web сервера стоял уже давно. Какого-то комплексного решения не было, поэтому я решил сделать хоть какие то первые шаги. Получить первые цифры. Благодаря которым можно было бы уже предметно разговаривать и продумывать дальнейшую стратегию.

Посмотреть, как работает можно, например здесь – бесплатный сервис хранения ссылок http://linkin.link. Про него я писал.

Вступление

Собственно, как тестировать web сервер? Если посмотреть на проблему в лоб – то веб сервер должен отдавать все страницы, которые были запрошены клиентами. И желательно отдавать быстро.

Конечно, есть множество других сценариев. Ведь web сервер не работает сам по себе, как правило, он как минимум работает с какой-нибудь БД, связь с которой — это отдельная большая тема. Опять же могут быть множество отдельных сервисов – авторизационных и прочих. Перед web сервером может стоять балансировщик нагрузок. Всё это может размещается в множестве виртуальных контейнеров, которые опять же могут быть на разных физических серверах. В общем это целый зоопарк каналов передачи данных – каждый из которых может стать узким горлышком.

Начинать надо с малого и для начала решил проверить самый простой и очевидный сценарий. Есть web сервер. Делаем на него запросы. Все запросы должны вернутся без ошибок и вовремя.

Задача поставлена. Тестировать решил так. На одной машине под windows 10 запускаю web сервер. На web сервере запущен сайт. На сайте размещено куча js, сss, mp4 файлов и, собственно, html страничка. Для простоты я просто взял страницу из готового сайта.

Чем досить сервер? Тут 2 пути – скачать что-то готовое или написать свой велосипед. Я решил остановится на втором варианте. И этот выбор я сделал по нескольким причинам.

Во-первых, это интереснее. Во-вторых, своя программа обладает большой гибкость, любой тестовый сценарий можно внедрять, как только он пришёл в голову. Да и, по собственным размышлениям, это займёт меньше времени чем поиск другой программы, скачивания, изучения интерфейса. А потом ещё столкнуться с фактом, что тот функционал, который есть, не подходит.

Httpdos

Изначально использовал TcpClient но по каким-то причинам он выдавал почти сразу на старте множество ошибочных загрузок. Не стал разбираться, а спустился пониже. Реализовал отправку на socket.

В программу добавил таблицу – url, количество удачных скачиваний, количество ошибок, размер закачки.

Ошибки считал по 2 сценариям. Все exception – связанные с открытием, отсылкой, приёмом данных. Собирательно если хоть, где что-то не так – убиваем socket, инкрементируем счётчик ошибок. Ещё добавил проверку длины данных. При первой закачке страницы – запоминается длина данных, все повторные закачки – сверяются с этим числом. Отклонение – считается ошибкой. Можно было бы добавить и что-то другое – но для начала мне и этого достаточно.

Всё для эксперимента готово. Запускаем web сервер. Запускаем httpdos – так назвал программу, чтобы дальше можно было использовать это короткое название. И вижу следующую картину.

Тут я уточню некоторые технические данные. Количество потоков делающие запросы получилось 1200. Эта цифра – количество url прочитанных из файла urls.txt, плюс я решил умножить все запросы в 20 раз. Все цифры взял из головы на момент написания программы. В любой момент можно поставить любые другие по желанию. Преимущество велосипеда.

Откуда такая цифра? По моим размышлениям она зависит от многих обстоятельств. Самая очевидное – это какого размера сами запросы. Как я писал выше – я просто скачиваю все данные с определённой web страницы, которая была взята из стороннего web проекта. И там много mp4 файлов, размер которых под 3 мегабайта. Если уменьшить размер запросов, например скачивать только css – наверняка количество обработанных запросов увеличится. Мне даже стало интересно, и я начал играть с исходным кодом как со стороны web сервера, так и со стороны httpdos. Там есть куча различных таймеров, буферов и прочего. Я смотрел, как то или иное изменение, окажет влияние на скорость.

Так же существенное влияние на скорость оказывало, то что web сервер и httpdos был запущен в режиме отладки в Visual Studio.

Решил параллельно с httpdos сделать загрузки js файла через браузер. Файл закачивается мгновенно. Т.е. httpdos не оказывает существенного влияния на web сервер.

Продолжаю эксперименты. Решил запустить три программы httpdos одновременно. И понаблюдать за результатами. То, что я увидел, и я является причиной появления этой статьи.

А у видел я, что по каким-то причинам спустя примерно минуту начали появляться ошибки загрузок.

И я начал расследование.

Такого поведения просто не должно быть!

Забегая вперёд, скажу, что даже не это побудило меня к дальнейшему расследованию. Ну пусть по каким-то причинам пару запросов из сотен тысяч не дойдут. Из моей практики – браузеры делают большое число одних и тех же запросов пока не получат запрошенные данные. Клиенты этого даже не заметят.

То, что произошло дальше заставило меня напрячься.

В процессе экспериментов я и так и сяк изгалялся над httpdos. И один сценарий привёл к неожиданным результатам.

Если запустить не менее 3 программ. Думаю, что такое количество связанно с количеством одновременных запросов в секунду. Начать dos атаку. Дождаться появления ошибок. Потом резко закрыть программы. То слушающий socket web сервера просто умирает! Вот так – нету никакой ошибки на стороне сервера. Все потоки работают. А socket ничего не принимает. Это уже ни в какие ворота.

Эксперименты показали, что socket оживал примерно через 4 минуты, но, если dos атаку проводить долго – socket умирал навсегда, по крайней мере я минут 15 ждал оживления, а дальше уже и не интересно было. Такого поведения просто не должно быть!

Эксперимент был проведён множество раз – результат всегда один и тот же.

Если перезапускать web сервер, т.е. получается мы пересоздаём слушающий socket, то socket начинал принимать клиентов сразу.

Первый шаг

Невозможно установить соединение, потому что целевой компьютер активно отказался от него. Обычно это происходит в результате попытки подключиться к службе, которая неактивна на чужом хосте, то есть к службе, на которой не запущено серверное приложение.

Ну… информативно(сарказм) однако. Вроде как это стоит понимать, что socket, к которому мы хотим подключится как бы и нету.

чем нагрузить сервер для тестирования. 593ac57d3a97e1386abc3e516b4e23e8. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-593ac57d3a97e1386abc3e516b4e23e8. картинка чем нагрузить сервер для тестирования. картинка 593ac57d3a97e1386abc3e516b4e23e8.

И что делать далее? В таком случае начинаю искать хоть какие-то зацепки, хоть какие-то отклонения от ожидаемого поведения. Поэтому придумываю кучу сценариев, обкладываю их отладчиками, трассировкой, сниффингом и прочим и наблюдаю.

Пару слов о socket

Как видно – для работы с слушающим socket нужно 3 действия. Создали. Слушаем. Принимаем клиентов. Схема настолько простая что программисту не остаётся никаких способов для манёвров, ну или возможностей отстрелить себе ногу.

Предполагается что используй вот так (куда ещё проще?) и не иначе – и всё у тебя должно работать. Но как показывает практика – есть нюансы.

Хоть схема использования и проста, я всё же решил провести пару экспериментов что бы отсеять весь лишний код из подозрений. Первое что я сделал это очистил код от лишних действий и поставил точку остановки сразу после конструкции:

Затем подвесил socket. Попытались присоединится клиентом. Программа висела в вышеприведённой строчки кода. Тут мы увидели, что проблема не в коде после socket, а где то внутри socket.

Дальше я решил поэкспериментировать с настройками открытия socket. Собственно, в своё время все настройки и так были исследованы, и оставлены только те, что нужно. Но в свете последних событий – никто не уйдёт от (подозрений) экспериментов.

Под подозрения попали следующие настройки.

Конечно, если подумать – ни одно из этих свойств не должно вызывать эффект, описанный выше, но в принципе вообще ничего не должно убивать socket. Но что-то же убивает. Да и провести этот эксперимент занимает десятки секунд, гораздо меньше, чем я этот текст пишу.

И вообще было проведено большое число разных спонтанных экспериментов. Пришла в голову идея. Изменил код. Запустил. Проверил. Забыл. Десятки секунд, не более.

Что касается тайм аутов. В коде сервера реализованы различные таймауты, но на более высоком уровне. В приёмнике есть таймауты на приём шапки http, определения длины body, расчёт времени на приём body исходя из длины body и сценария наихудшего канала связи, например 1024 кб/c.

Примерно такие же правила и на отправку.

И если таймауты выходят – socket клиента закрывается и удаляется. Для socket вызывается shutdown и close. Всё как и предписывает microsoft.

Поставил таймауты для resive/transmite 2000ms. Не помогло. Идём далее.

Что это за параметр? Wiki говорит:

Получает или задает значение, задающее время существования (TTL) IP-пакетов

Т.е. при прохождении очередного шлюза параметр уменьшается на 1. При достижении 0 – пакет удаляется. И вроде это не наш случай. Потому как наша система вся на localhost. Но! При гугление я нашёл следующую информацию.

Там было сказано, что windows от этого параметра рассчитывает двойное время нахождения socket в режиме TIME_WAIT. Про этот режим более подробно ниже.

Поставил ttl в минимально возможное значение. Не помогло.

Утечка sockets?

Далее я подумал – сервер открывает каждую секунду около 6000 тысяч sockets и закрывает их. И всё это крутится на кучи асинхронных Task. Вдруг количество открытых сокетов и закрытых не совпадает? И есть, некая утечка sockets?

Быстро набросав код – принцип которого заключается в инкременте глобальной переменной при открытии socket и декременте при закрытии и вывода этого числа в консоль.

Весь дополнительный код состоял из 3 блоков:

Разумеется, каждый блок размещается в нужном месте.

Запустив программы, я получил следующее:

Видео можно разделить на три части. Запуск. Рабочее состояние – длится около 3 минут. В этом состоянии ни одной ошибки. И первое появление ошибки. Собственно, вторую часть я вырезал как не интересную.

Как же нам интерпретировать результат? Во-первых, мы видим число примерно 400 выводящееся каждую секунду.

Как работает веб сервер? Идеальный сервер приняв клиента мгновенно формирует ответ, отправляет его клиенту и мгновенно закрывает socket (хотя в реальности socket не закрывается а ожидает следующих запросов, ну условимся что так работает идеальный сервер). Поэтому количество открытых socket в идеальном сервере каждую секунду было бы 0. Но тут мы видим, что каждую секунду у нас примерно 400 обрабатывающихся клиентов. Что ж, для неидеального сервера вполне норма. Вообще количество одновременных клиентов в нашем сервере задаётся глобальной настройкой. В данном случае 10000 – что значительно выше 400.

Так же мы видим, что периодически подпрыгивающее значение до 1000-2000. Связанно это может быть с чем угодно. При желании можно и это выяснить. Может сборщик мусора, может что ещё. Но, собственно, ничего криминального в этом нет.

И вот появились первые ошибки. Я начал закрывать программы. На видео виден характерный момент – при закрытии второй программы, в последней оставшейся программе, посыпались ошибки открытия socket. Это в очередной раз показал своё лицо баг – который мы так пытаемся отловить, пока безуспешно. Одна радость – повторяется он регулярно, поэтому хоть есть возможность поиска. Сама же эта ошибка нам пока ничего не даёт.

Главная цель текущего эксперимента – сопоставить количество открытых и закрытых socket. Окончательная цифра 0. Всё, как и должно быть. Ладно идём дальше.

Динамический диапазон портов

Далее расследование завело меня в область настроек windows. Должны же быть какие-то настройки для работы tcp/ip стека? Гугление мне подкинуло множество, но особо я хотел бы остановится на наиболее подходящих к нашему случаю.

Если выделять тысячи портов в секунду – то можно и исчерпать их всех.

Такой способ выдаёт socket с портом из динамического пула windows. Т.е. windows сама решает какой порт тебе выдать. Я поменял этот код на другой – где я сам указывал порты. Но первый запуск показал, что диапазон выбранных мною портов был нашпигован как изюм открытыми портами, плюс доступ к некоторым портам выдавал странные ошибки о некорректном доступе. Это заставляло меня усложнять программу – делать код поиска открытых портов

Поискав готовое решение я увидел, что это не простой способ – в одну строчку. И я не стал развивать эту тему дальше. Windows виднее кокой мне порт дать.

В дальнейшем я и убедился в своей правоте. Как оказалось Microsoft изменила этот диапазон, и он составляет 49152-65535. И того где-то 15k портов. Явно меньше, чем 65535

Поэтому первая настройка – увеличиваем этот диапазон.

Я применил следующую команду:

netsh int ipv4 set dynamicport tcp start=10000 num= 55535

Команду запускаем под администратором. Проверить значение можно командой:

netsh int ipv4 show dynamicport tcp

Изменить то изменили – но как проверить, что диапазон действительно расширен? Да и нужно ещё узнать повлияла ли эта настройка на наш баг.

Делаем вывод на стороне сервер, всех портов подключившихся клиентов. Ну и пытаемся увидеть какие-нибудь отклонения от нормы. Вдруг кусок выпадет из списка?

Что показало нам запуск? При старте одной программы вылетела ошибка одного подключения. Не будем на это обращать внимание. А то так можно закопаться по уши в отладке. Дальше работало всё, как и ожидалось. Во-первых, мы чётко увидели, что диапазон выделяемых портов действительно стал 10000-65535. Во-вторых, порты выделяются последовательно без каких-то видимых провалов. Достигнув максимума, цикл повторяется. Я прогнал несколько циклов – никаких отклонений.

Далее я начал закрывать программы – и при закрытии второй программы – серверный socket завис. Порты перестали выделятся. Во второй программе httpdos посыпались ошибки открытия socket.

Выводы – проблема не в портах. По крайней мере порты явно не заканчиваются.

TIME WAIT

А что у нас есть вообще по протоколу TCP? Идём сюда и внимательно читаем.

Под подозрение попадает одно состояние TIME WAIT. Это одно из стояний, в котором может находится socket, т.е. пара ip+port. После его закрытия.

Получается, что мы закрыли socket – но он ещё будет недоступен. Поиск показал, что это время находится в районе 4 минут.

Если бы мы играли в игру холодно-горячо, то я бы заорал горячо! Горячо! Похоже это именно наш случай.

Но зачем такое странное поведение. Опять же из справки получил пояснение. Т.к. протокол tcp/ip гуляет по сети пакетами, а сами пакеты могут пойти по разным маршрутам. И вообще застрять на некоторое время на каком-нибудь шлюзе, может получится ситуация, когда мы открыли socket, поработали с удалённым сервером. Закрыли socket. Потом этот socket открывает другая программа – а ей начинают валится пакеты от предыдущей сессии. Как раз время таймаута и выбрано что бы отставшие все пакеты в сети удалились как мусорные.

OK, а можно ли изменить этот параметр? Оказывается в Windows есть целая ветка реестра, отвечающая за параметры tcp протокола.

Нас интересуют пока 2 параметра:

Цель установить минимальное значение. Минимальное значение 30. Что означает что через 30 секунд порт опять будет доступен. Устанавливаем. Ну а далее наша стандартная проверка.

Запускаем сервер. Запускаем клиенты. Досим. Дожидаемся отказа socket. Потом запускаем консоль и вводим команду:

Такое ощущение что весь выделенный диапазон портов находится в состоянии TIME WAIT. Это пока соответствует ожиданиям. Ждём 30с. Повторяем команду. Листинг уменьшился в разы. Все порты с WAIT TIME пропали.

Проверяем серверный socket на оживление. Глух ((( А такие надежды были на эту настройку.

Впрочем, определённые выводы сделать можно. Настройка наша работает. Пауза 30с. Оставляем – полезная настройка для нагруженного сервера.

Wireshark

Решил посмотреть, что нам покажет Wireshark. Кто не знает — это мощнейший анализатор всевозможных протоколов, в том числе и tcp/ip. До недавнего времени в программе не была реализована функция прослушки localhost и приходилось производить некоторые танцы с бубном. Ставить виртуальную сетевую карту. Трафик пускать через неё. А Wireshark уже мог подключатся к прослушке этой карты.

Недавно подвезли возможность прослушки localhost – что очень облегчило работу.

Далее всё стандартно. Запускаем сервер, клиентов. Убиваем слушающий socket.

Запускаем Wireshark – ставим фильтр на 80 порт. Открываем браузер – пытаемся закачать файл javascript.

Вот какое непотребство мы увидели в сниффере:

чем нагрузить сервер для тестирования. image loader. чем нагрузить сервер для тестирования фото. чем нагрузить сервер для тестирования-image loader. картинка чем нагрузить сервер для тестирования. картинка image loader.

Видно, наш запрос. Браузер с порта 36036 пытается достучатся к порту 80. Выставляет флаг SYN. Это стандартно. Но вот с порта 80 нам возвращается флаг RST — оборвать соединения, сбросить буфер. Всё. И так по кругу.

Вывод. Wireshark – нам особо не помощник. Разве только мы увидели, что слушающий socket не мёртв совсем, а отвечает. Он работает по какой-то своей внутренней логике, а не просто умер.

Журнал windows

Решил посмотреть – может что в журнале событий windows есть что-то интересное. Для этого захожу в журнал.

Панель управления-> Администрирование-> Управление компьютером-> Служебные программы-> Просмотр событий-> Журналы Windows

Либо запустите eventvwr.msc

Там, разумеется, есть миллионы записей. И чтобы не копаться в этих миллионах, я делаю следующее. Убиваю socket. Захожу в журнал – и чищу подразделы. Захожу в браузер – пытаюсь скачать файл. Захожу в журнал – и смотрю что там только что появилось.

К сожалению, никаких событий, кусающихся моей проблемы, не появилось. Я даже нашёл такой раздел Microsoft/Windows/TCPIP. Но кроме одинокой записи – “работает”, там ничего не было.

Финал?

Поиск в интернете всей доступной информации по проблеме периодически выдавал мне страницы подобной этим:

И ещё во многих других местах.

Отсюда я сделала 2 вывода – я со своей проблемой не одинок, и как минимум периодически с ней сталкиваются и другие.

Есть ещё 2 параметра TCP стека с которыми можно поэкспериментировать.

Поиск по этим параметрам для Windows 10 ничего не дал. Только для Windows 2003-2008 Server. Может плохо искал (наверняка). Но я всё же решил их проверить.

Установил следующие значения:

TcpMaxDataRetransmissions REG_DWORD: 00000005 (hex)

Перезагрузился. Повторил в который раз все процедуры. И….

Socket жив. Всё проверив несколько раз, путём добавления и удаления из реестра параметров с последующей перезагрузкой компьютера. Все эксперименты показали, что с параметрами – socket остаётся жив. Это всё?

В этом месте был завершающий текст с выводами и размышления на тему почему именно эти параметры помогли.

На следующий день, я решил закрепить полученную информацию. Запускаю эксперимент – socket мёртв. Мы вернулись к тому, с чего начинали!

Эти параметры оказались бесполезны в решении нашей проблемы. Но я их всё-таки оставил – потому как по смыслу они полезные.

Финал

Продолжая эксперименты, я обнаружил в коде один хитрый перехватчик исключений на слушающим socket. Точка остановки в этом месте показала, что при возникновении нашего случая – сюда начали валится куча exception со следующим сообщением:

Удаленный хост принудительно разорвал существующее подключение.

В этом exсeption была паузу. С пояснением – исключение на socket случай неординарный, например socket занят другим приложением, делаем паузу что бы всё утряслось и в лог не сыпалось миллионы сообщений.

Как оказалось не неординарный.

Картина сложилась

Получается, что приёмный socket набрал большое число входящих подключений, которые оборвались, и больше не принимает новые подключения пока поток висел в exception на паузе.

Выводы

Ну что ж. Я, конечно, ожидал что геройски одержу победу над некоей эпичной ошибкой. А всё оказалось очень банально. Собственно, как всегда.

Все эксперименты у меня заняли где-то полтора дня. Эту статью я писал намного больше.

Из плюсов – цель эксперимента достигнута. Сервер провёл часы под нагрузкой, вряд ли я бы столько тестировал его, не будь этой ошибки. Плюс я отдельно проверил некоторые важные механизмы работы сервера. Т.к. искал ошибку – эта проверка была интересна. Если бы просто проверял – то это была бы наискучнейшая работа.

Узнал новую информацию по поводу работы сети – эти знания пригодятся впоследствии при решения очередного непонятного бага.

Почему у меня заняло так много времени на поиск банального Delay? Я думал над этим и пришёл к выводу, что все эксперименты уводили в сторону от ответа. Сложившееся картина показывала нам что умирал именно socket. Переставал принимать подключения. Спустя время оживал. Все сниферы показывали, что подключений не происходит.

Опять же было неправильное представление, что серверный socket работает в отдельном потоке. И в любом случае должен принимать клиентов. Поэтому я и скал проблему в настройках socket и tcp стека. Главная проблема – я думал поток висит на socket. А в нашем аварийном случае он висел на exeption в Delay.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *