Как измерить пропускную способность и предел параллелизма через прокси в k6 и JMeter
Содержание статьи
- Введение: зачем знать предел заранее, а не в момент большой выгрузки
- Предварительная подготовка: инструменты, требования и доступы
- Базовые понятия простым языком
- Шаг 1: готовим тестовую цель и данные прокси
- Шаг 2: понимаем правильную методику нагрузки
- Шаг 3: k6 - готовый сценарий с прокси и ступенями нагрузки
- Шаг 4: jmeter - тот же сценарий с настройкой прокси в плане теста
- Шаг 5: отличаем предел прокси от предела клиента и лимита сервера - три проверки
- Шаг 6: что делать с результатом - потоки, пул и время выгрузки
- Шаг 7: этика нагрузки и щадящие режимы
- Проверка результата: чек-лист готовности
- Типичные ошибки и решения
- Дополнительные возможности и оптимизация
- Faq: частые вопросы по замеру пропускной способности через прокси
- Заключение
Работа через прокси почти всегда упирается в один вопрос: сколько параллельных запросов реально выдержит связка "ваш клиент - прокси - целевой сервер" до того, как задержки взлетят, а ошибки начнут сыпаться. Этот гайд научит вас измерять это заранее, а не в момент большой выгрузки, когда счёт идёт на часы простоя.
Введение: зачем знать предел заранее, а не в момент большой выгрузки
Представьте типичную ситуацию. Вы запускаете большую задачу по сбору публичных данных через пул прокси. Всё идёт хорошо на первых тысячах запросов, а потом задержки растут, часть запросов начинает падать по таймауту, и вы не понимаете - виноват ваш код, прокси или целевой сервер. К этому моменту вы уже потеряли время и, возможно, данные.
Гораздо разумнее заранее провести управляемый нагрузочный тест и найти точку деградации. Тогда вы сможете подобрать безопасное число потоков и правильно спланировать время выгрузки.
Что получит читатель в итоге
После прохождения гайда вы сможете самостоятельно:
- Собрать корректный нагрузочный сценарий в k6 и запустить его через прокси.
- Повторить тот же сценарий в JMeter с настройкой прокси в плане теста.
- Читать отчёт: понимать RPS (запросов в секунду), задержки по перцентилям и долю ошибок.
- Отличать предел прокси от предела вашего клиента и от лимита целевого сервера.
- Пересчитывать результаты в число потоков, размер пула и ожидаемое время выгрузки.
Для кого этот гайд
Материал рассчитан на инженеров, аналитиков данных и разработчиков среднего уровня. Если вы уже писали простые скрипты на JavaScript или запускали программы из командной строки, вам будет комфортно. Для новичков мы объясняем каждый термин простыми словами.
Что нужно знать заранее
Достаточно базовых навыков: как открыть терминал, установить программу и отредактировать текстовый файл. Знание HTTP на уровне "что такое запрос и ответ" будет плюсом, но не обязательно.
Сколько времени потребуется
На установку инструментов уйдёт около 30-40 минут. Первый рабочий тест в k6 вы запустите за час. Полный цикл с JMeter и анализом займёт 3-4 часа спокойной работы.
⚠️ Внимание: Все примеры в гайде предназначены для тестирования вашего собственного стенда или ресурсов, на нагрузку которых у вас есть явное разрешение. Нагрузочное тестирование чужих сервисов без согласия недопустимо. Об этике мы отдельно поговорим в конце.
Предварительная подготовка: инструменты, требования и доступы
Прежде чем измерять, нужно собрать рабочее окружение. Здесь мы перечислим всё необходимое и покажем, как установить каждый компонент.
Необходимые инструменты и доступы
- k6 - лёгкий инструмент нагрузочного тестирования, сценарии пишутся на JavaScript.
- Apache JMeter - классический инструмент с графическим интерфейсом на Java.
- Java 17 или новее - требуется для работы JMeter.
- Доступ к прокси от Proxeon: адрес, порт, логин и пароль. Эти данные вы получаете в личном кабинете сервиса.
- Тестовая цель - ваш собственный стенд или согласованный ресурс.
Системные требования
Для комфортной работы подойдёт машина с 4 ядрами процессора и 8 ГБ оперативной памяти. Для высокой нагрузки (тысячи виртуальных пользователей) желательно 8 ядер и 16 ГБ. Операционная система - Windows, macOS или Linux, все инструменты кроссплатформенные.
Совет: Запускайте генератор нагрузки на отдельной машине или в отдельном облачном сервере. Так вы не спутаете нагрузку на ваш ноутбук с нагрузкой на прокси.
Установка k6
- Откройте официальный способ установки для вашей системы: на macOS через менеджер пакетов Homebrew командой brew install k6.
- На Windows используйте менеджер пакетов Chocolatey: choco install k6.
- На Linux скачайте пакет из репозитория проекта и установите его через системный менеджер пакетов.
- Проверьте установку командой k6 version - в ответ вы увидите номер версии.
✅ Проверка: Если команда k6 version выводит строку с версией и не выдаёт ошибку "команда не найдена", инструмент установлен правильно.
Установка Java и JMeter
- Установите OpenJDK версии 17 или новее и проверьте командой java -version.
- Скачайте архив Apache JMeter с официального сайта проекта в разделе загрузок.
- Распакуйте архив в удобную папку, например в домашний каталог.
- Перейдите в подпапку bin внутри распакованного JMeter.
- Запустите файл jmeter (на Linux и macOS) или jmeter.bat (на Windows).
- Дождитесь появления графического окна с деревом плана теста слева.
✅ Проверка: Если открылось окно JMeter с элементом "Test Plan" в дереве слева, всё готово.
Резервные копии и подготовка стенда
Если тестируете свой сервис, заранее снимите снапшот или бэкап данных стенда. Нагрузка не должна повредить продакшн. По возможности используйте копию окружения, а не боевой сервер.
Базовые понятия простым языком
Чтобы читать отчёты и не путаться в терминах, разберём ключевые понятия.
Пропускная способность и RPS
Пропускная способность - это сколько полезной работы система выполняет за единицу времени. В контексте HTTP её обычно измеряют в RPS - запросах в секунду. Чем выше RPS при приемлемых задержках, тем лучше.
Задержка и перцентили
Задержка (latency) - время от отправки запроса до получения ответа. Одно среднее значение обманчиво, потому что редкие медленные запросы в нём растворяются. Поэтому используют перцентили.
Перцентиль p95 означает: 95 процентов запросов были быстрее этого значения, а 5 процентов - медленнее. Перцентиль p99 показывает поведение самых медленных запросов. Именно p95 и p99 лучше всего отражают реальный опыт под нагрузкой.
Доля ошибок и момент деградации
Доля ошибок - процент запросов, завершившихся неуспешно: таймауты, отказы соединения, коды ответа 5xx. Момент деградации - точка, где рост нагрузки перестаёт увеличивать RPS, зато резко растут задержки и ошибки. Это и есть искомый предел.
Параллелизм и виртуальные пользователи
Параллелизм - сколько запросов выполняется одновременно. В k6 его задают через VU (virtual users, виртуальные пользователи), в JMeter - через число потоков в группе (Thread Group). Один VU или поток отправляет запросы последовательно, а множество их создают параллельную нагрузку.
Прокси в цепочке нагрузки
Прокси - промежуточный узел, через который идут ваши запросы. У него есть собственный предел числа одновременных соединений и пропускной способности. Наша цель - понять, на каком уровне параллелизма этот узел начинает быть узким местом.
Совет: Держите в голове формулу Литтла: среднее число одновременных запросов примерно равно RPS, умноженному на среднюю задержку в секундах. Она помогает быстро прикидывать нужный параллелизм.
Шаг 1: Готовим тестовую цель и данные прокси
Цель этапа: получить рабочий адрес цели и корректно оформленную строку подключения к прокси.
- Определите URL цели, которую будете нагружать. Пусть это будет ваш стенд, например адрес вида https://stend.local/api/health.
- Убедитесь, что цель отвечает быстро и стабильно при одиночном запросе через обычный браузер или утилиту curl.
- Возьмите данные прокси Proxeon из личного кабинета: хост, порт, имя пользователя и пароль.
- Соберите строку подключения формата http://ИМЯ:ПАРОЛЬ@ХОСТ:ПОРТ. Для примера: http://user:pass@proxy.proxeon.net:8000.
- Проверьте прокси одиночным запросом curl, подставив ваши данные вместо примера.
Пример проверочного запроса:
curl -x http://user:pass@proxy.proxeon.net:8000 -H "Accept: application/json" https://stend.local/api/health⚠️ Внимание: Никогда не храните логин и пароль прокси прямо в коде, который попадёт в репозиторий. Используйте переменные окружения. Мы покажем это в следующих шагах.
Ожидаемый результат: curl через прокси возвращает корректный ответ от вашей цели без ошибок соединения.
Возможные проблемы: если curl зависает - проверьте порт и файрвол. Если возвращается ошибка авторизации 407 - перепроверьте логин и пароль.
✅ Проверка: Вы видите тело ответа от цели, полученное именно через прокси. Значит цепочка работает.
Шаг 2: Понимаем правильную методику нагрузки
Цель этапа: усвоить, почему разовый залп бесполезен и как строить корректный профиль нагрузки.
Почему разовый залп вводит в заблуждение
Если вы одномоментно запустите тысячу запросов, вы получите красивое, но бессмысленное число. Такой залп не показывает устойчивое поведение. Система может проглотить пиковый всплеск за счёт буферов, а затем деградировать. Или, наоборот, захлебнуться на старте из-за холодных соединений.
Три фазы правильного теста
Корректный нагрузочный тест состоит из трёх фаз:
- Разогрев (warm-up). Первые 30-60 секунд плавно поднимаем нагрузку. Прогреваются пулы соединений, кэши DNS и внутренние структуры. Данные разогрева в итоговую статистику не включаем.
- Ступенчатый рост (ramp-up steps). Увеличиваем параллелизм ступенями: например 10, 25, 50, 100, 200 VU, задерживаясь на каждой ступени по 1-2 минуты. Так мы видим, на какой ступени начинается деградация.
- Стабильная полка (steady state). Фиксируем нагрузку на уровне чуть ниже предела и держим её 5-10 минут. Полка показывает, стабильна ли система под постоянной нагрузкой, нет ли утечек и накопления очередей.
Совет: Никогда не делайте выводы по первым 30 секундам теста. Пусть система выйдет на установившийся режим, только потом смотрите на цифры.
Что фиксируем на каждой ступени
- Достигнутый RPS.
- Задержки p50, p95, p99.
- Долю ошибок.
- Число активных VU или потоков.
Момент деградации определяем так: находим ступень, после которой RPS перестал расти, а p95 и доля ошибок начали резко увеличиваться. Предыдущая ступень - ваша безопасная рабочая точка.
✅ Проверка: Вы можете своими словами объяснить, чем разогрев отличается от полки и зачем нужен ступенчатый рост.
Шаг 3: k6 - готовый сценарий с прокси и ступенями нагрузки
Цель этапа: создать и запустить рабочий сценарий k6, который проходит разогрев, ступени и полку через прокси.
Как k6 работает с прокси
k6 читает адрес прокси из переменных окружения HTTP_PROXY и HTTPS_PROXY. Это удобно: вам не надо хардкодить данные в скрипт, достаточно передать их при запуске.
Готовый скрипт load-test.js
Создайте файл load-test.js и вставьте в него следующий код. Замените адрес цели на свой.
import http from 'k6/http'; import { check, sleep } from 'k6'; import { Trend, Rate, Counter } from 'k6/metrics'; const latency = new Trend('req_latency', true); const errors = new Rate('req_errors'); const ok = new Counter('req_ok'); export const options = { discardResponseBodies: true, thresholds: { req_errors: ['rate<0.02'], http_req_duration: ['p(95)<1500', 'p(99)<3000'], }, scenarios: { ramp: { executor: 'ramping-vus', startVUs: 0, stages: [ { duration: '1m', target: 10 }, { duration: '2m', target: 25 }, { duration: '2m', target: 50 }, { duration: '2m', target: 100 }, { duration: '2m', target: 200 }, { duration: '5m', target: 200 }, { duration: '1m', target: 0 }, ], gracefulRampDown: '30s', }, }, }; const TARGET = __ENV.TARGET_URL || 'https://stend.local/api/health'; export default function () { const res = http.get(TARGET, { timeout: '10s', tags: { name: 'target' } }); latency.add(res.timings.duration); const good = check(res, { 'status is 200': (r) => r.status === 200 }); errors.add(!good); if (good) ok.add(1); sleep(0.5); }Как запустить сценарий через прокси
- Откройте терминал в папке со скриптом.
- Задайте переменные окружения с адресом прокси и целью. На Linux и macOS выполните экспорт переменных.
- Запустите k6 командой запуска скрипта.
Пример запуска на Linux и macOS:
export HTTP_PROXY=http://user:pass@proxy.proxeon.net:8000 export HTTPS_PROXY=http://user:pass@proxy.proxeon.net:8000 export TARGET_URL=https://stend.local/api/health k6 run load-test.jsНа Windows в PowerShell переменные задаются через синтаксис с $env:
$env:HTTP_PROXY="http://user:pass@proxy.proxeon.net:8000"; $env:HTTPS_PROXY="http://user:pass@proxy.proxeon.net:8000"; $env:TARGET_URL="https://stend.local/api/health"; k6 run load-test.jsСовет: Параметр discardResponseBodies отключает хранение тел ответов в памяти. Это снижает нагрузку на сам генератор и помогает не спутать его перегрузку с пределом прокси.
Чтение отчёта k6
После завершения теста k6 выводит сводку. Обратите внимание на ключевые строки:
- http_reqs - общее число запросов и средний RPS в скобках. Это ваша пропускная способность.
- http_req_duration - задержки, где показаны avg, min, med, max и перцентили p(90), p(95).
- req_errors и http_req_failed - доля ошибок.
- vus - число виртуальных пользователей в моменте.
Строка thresholds покажет, прошли ли ваши пороги. Если рядом со строкой стоит крестик, порог нарушен - значит на этой конфигурации предел уже достигнут или превышен.
⚠️ Внимание: Значения target в stages подбирайте под свою систему. Значение 200 VU дано как пример. Если ваша цель или тарифный лимит прокси меньше, начните с более скромных ступеней, например до 50.
Ожидаемый результат: тест завершился, вы видите сводку с RPS, перцентилями и долей ошибок.
Возможные проблемы: если все запросы падают, проверьте переменные прокси. Если генератор ест 100 процентов CPU - уменьшите число VU или запустите тест на более мощной машине.
✅ Проверка: В сводке k6 отображается ненулевой http_reqs, а доля ошибок ниже вашего порога х��тя бы на первых ступенях.
Шаг 4: JMeter - тот же сценарий с настройкой прокси в плане теста
Цель этапа: собрать эквивалентный план в JMeter с прокси, ступенями и сбором метрик.
Создаём группу потоков
- В открытом JMeter кликните правой кнопкой по элементу Test Plan.
- Выберите Add - Threads (Users) - Thread Group.
- В поле Number of Threads задайте максимальное число потоков, например 200.
- В поле Ramp-up period укажите время выхода на полную нагрузку в секундах, например 540, чтобы повторить ступенчатый рост из k6.
- В поле Loop Count поставьте флажок Infinite, а длительность зададим таймером и планировщиком.
Настройка прокси в HTTP Request Defaults
Чтобы не прописывать прокси в каждом запросе, зададим его один раз.
- Кликните правой кнопкой по Thread Group и выберите Add - Config Element - HTTP Request Defaults.
- В открывшемся элементе найдите вкладку с настройками прокси-сервера.
- В поле Server Name or IP (в блоке Proxy) введите хост прокси, например proxy.proxeon.net.
- В поле Port Number (Proxy) введите порт, например 8000.
- В поля Username и Password (Proxy) введите ваши логин и пароль.
Добавляем сам HTTP-запрос
- Кликните правой кнопкой по Thread Group, выберите Add - Sampler - HTTP Request.
- В поле Protocol впишите https.
- В поле Server Name or IP впишите домен цели, например stend.local.
- В поле Path впишите путь, например /api/health.
- В поле Method оставьте GET.
Добавляем задержку между запросами
- Кликните правой кнопкой по HTTP Request и выберите Add - Timer - Constant Timer.
- В поле Thread Delay введите 500 миллисекунд, чтобы повторить sleep из k6.
Настраиваем сбор метрик
- Кликните правой кнопкой по Thread Group и добавьте Add - Listener - Summary Report.
- Добавьте также Add - Listener - Aggregate Report - он показывает перцентили.
- Для длительных тестов не используйте графические слушатели, они едят память. Вместо этого сохраняйте результаты в файл.
Совет: Для тяжёлых тестов запускайте JMeter в неграфическом режиме командой из терминала. Так генератор тратит ресурсы на нагрузку, а не на отрисовку графиков.
Пример запуска в неграфическом режиме:
jmeter -n -t plan.jmx -l results.jtl -e -o reportЗдесь -n запускает без графики, -t указывает файл плана, -l - файл с сырыми результатами, а -e -o создаёт HTML-отчёт в папке report.
Чтение отчёта JMeter
Откройте index.html из папки report. Ключевые показатели:
- Throughput - пропускная способность в запросах в секунду.
- Response Times Percentiles - график перцентилей задержки.
- Error percentage - доля ошибок.
- Active Threads Over Time - как рос параллелизм.
⚠️ Внимание: В аутентификации прокси JMeter иногда требует дополнительной настройки Basic-авторизации. Если видите массовые 407, добавьте элемент HTTP Authorization Manager с данными прокси.
Ожидаемый результат: HTML-отчёт JMeter открывается и показывает throughput, перцентили и долю ошибок.
✅ Проверка: Значения throughput и перцентилей в JMeter сопоставимы с результатами k6 при одинаковых ступенях. Небольшие расхождения нормальны.
Шаг 5: Отличаем предел прокси от предела клиента и лимита сервера - три проверки
Цель этапа: точно определить, какой из трёх узлов стал узким местом.
Когда вы видите деградацию, важно понять её источник. Проведите три контрольные проверки.
Проверка 1: не упирается ли ваш клиент
- Во время теста откройте системный монитор на машине-генераторе.
- Следите за загрузкой CPU и оперативной памяти процесса k6 или JMeter.
- Проверьте лимит открытых файловых дескрипторов на Linux командой ulimit -n.
Если CPU генератора близок к 100 процентам или упёрлись в лимит дескрипторов - виноват клиент, а не прокси. Поднимите лимит дескрипторов, уменьшите число VU или используйте более мощную машину.
Совет: Признак перегрузки клиента - рост задержек одновременно с ростом загрузки CPU генератора при неизменном RPS. Прокси тут ни при чём.
Проверка 2: не упирается ли целевой сервер
- Запустите короткий тест напрямую, без прокси, убрав переменные HTTP_PROXY и HTTPS_PROXY.
- Сравните RPS и перцентили с результатами через прокси.
Если и напрямую, и через прокси предел RPS почти одинаковый - узкое место находится в целевом сервере. Прокси добавляет лишь небольшую фиксированную задержку.
⚠️ Внимание: Тест напрямую делайте только против вашего собственного стенда. Не нагружайте чужие ресурсы без разрешения даже в диагностических целях.
Проверка 3: изолируем сам прокси
- Поднимите на своём стенде лёгкую заглушку, которая мгновенно отвечает 200 OK с пустым телом.
- Прогоните тест через прокси против этой заглушки.
Заглушка отвечает почти мгновенно, поэтому задержки и предел RPS теперь определяются в основном прокси и сетью. Если RPS упирается в потолок именно на заглушке - вы нашли предел прокси.
Сведём логику в простую таблицу решений словами:
- CPU генератора высок, RPS не растёт - предел клиента.
- Напрямую и через прокси одинаково - предел целевого сервера.
- На быстрой заглушке через прокси RPS упёрся - предел прокси.
Ожидаемый результат: вы называете конкретный узел, ограничивающий вашу связку.
✅ Проверка: Вы провели все три проверки и можете обосновать, где именно находится узкое место.
Шаг 6: Что делать с результатом - потоки, пул и время выгрузки
Цель этапа: превратить цифры теста в практические настройки вашей рабочей задачи.
Выбор безопасного числа потоков
Возьмите ступень перед моментом деградации. Допустим, при 100 VU вы получили стабильные 180 RPS, p95 около 900 мс и ошибки ниже 1 процента, а при 200 VU RPS не вырос, зато p95 подскочил до 4 секунд. Тогда рабочая точка - около 100 VU, а для запаса возьмите 80-90.
Расчёт размера пула прокси
Если один узел прокси устойчиво держит N параллельных соединений, а вам нужно M одновременных, то минимальный размер пула равен M делить на N с округлением вверх плюс запас. Запас в 20-30 процентов покрывает моменты, когда часть соединений занята медленными ответами.
Совет: Всегда закладывайте запас пула. Реальные ответы медленнее заглушки, а значит соединения удерживаются дольше и параллелизм фактически выше расчётного.
Оценка времени выгрузки
Формула простая: время в секундах равно общему числу запросов делить на устойчивый RPS. Если вам нужно собрать 1 000 000 запросов при устойчивых 180 RPS, это примерно 5556 секунд, то есть около 1 часа 33 минут без учёта пауз и повторов.
- Возьмите устойчивый RPS с рабочей ступени.
- Разделите общий объём задачи на этот RPS.
- Добавьте 15-20 процентов на повторы неудачных запросов и паузы.
Пример расчёта на псевдокоде для наглядности:
total = 1000000; rps = 180; base_sec = total / rps; final_sec = base_sec * 1.2;