惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V2EX - 技术
V2EX - 技术
P
Privacy International News Feed
Security Latest
Security Latest
H
Hacker News: Front Page
T
Tenable Blog
The Hacker News
The Hacker News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Security @ Cisco Blogs
Project Zero
Project Zero
O
OpenAI News
AI
AI
Spread Privacy
Spread Privacy
C
CERT Recently Published Vulnerability Notes
The Last Watchdog
The Last Watchdog
G
GRAHAM CLULEY
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Scott Helme
Scott Helme
Application and Cybersecurity Blog
Application and Cybersecurity Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
NISL@THU
NISL@THU
A
Arctic Wolf
T
Threat Research - Cisco Blogs
PCI Perspectives
PCI Perspectives
N
News and Events Feed by Topic
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cybersecurity and Infrastructure Security Agency CISA
Simon Willison's Weblog
Simon Willison's Weblog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
Google Online Security Blog
Google Online Security Blog
罗磊的独立博客
L
LINUX DO - 最新话题
U
Unit 42
S
Security Affairs
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
博客园 - 【当耐特】
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
月光博客
月光博客
Engineering at Meta
Engineering at Meta
腾讯CDC
F
Full Disclosure
Cyberwarzone
Cyberwarzone
S
SegmentFault 最新的问题
Recorded Future
Recorded Future
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
The Cloudflare Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Нагрузочное тестирование с Apache JMeter: Best Practices
sproshchaev · 2026-04-23 · via Все публикации подряд на Хабре

Уровень сложностиСредний

Время на прочтение8 мин

Охват и читатели1.2K

Туториал

Введение

Всем привет, меня зовут Сергей Прощаев. Я Tech Lead и руководитель направления Java | Kotlin разработки в FinTech, а также преподаю на курсах разработки и архитектуры в OTUS. В этой статье я расскажу не просто про кнопки в Apache JMeter, а про то, как перестать играть в нагрузочное тестирование и начать получать от него реальную пользу, которая спасает нервы в ночь релиза.

Видел много отчетов о нагрузочном тестировании. Знаете, что их объединяет в 80% случаев? Они рисуют красивые графики роста трафика и пишут «Система стабильна, ограничение — БД». На этом всё. А через неделю после релиза прод падает в час пик, потому что никто не проверил, как поведет себя кэш при 100% заполнении хипа или как работает пул соединений, когда один из инстансов сервиса начинает тупить.

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

Знакомство с Apache JMeter: Почему он, а не модный Gatling?

Часто можно услышать от новичков: «JMeter — это же прошлый век, UI некрасивый, Java‑стек, давай лучше Gatling, там кодом, это стильно, модно, молодежно». Доля правды в этом есть, но это взгляд разработчика, который хочет писать скрипты как код. Взгляд системного аналитика или инженера по нагрузке немного другой.

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

  1. Протоколы. Помимо HTTP(S), он из коробки тянет JDBC, Kafka, JMS, gRPC (через плагины). Вам не нужно собирать отдельный проект на Scala, чтобы долбиться в базу данных прямыми запросами или проверить очередь сообщений.

  2. Визуализация для «соседа». Когда вам нужно показать тестировщику, как именно мы парсим CSRF‑токен из страницы, открыть.jmx файл в UI куда проще, чем объяснять регулярки в коде.

  3. Экосистема. Плагин JMeter Plugins Manager дает готовые графики процентилей и затупы потоков без необходимости писать экспортеры в Prometheus.

Конечно, у него есть недостатки — он прожорлив по памяти при отрисовке больших графиков в GUI. Но сильные инженеры знают правило: GUI — только для отладки. Нагрузку гоняем исключительно в CLI‑режиме. И дальше я покажу, как это работает.

Создание и отладка HTTPS‑скрипта: главная ловушка

Самая частая ловушка при создании скрипта — запись через HTTP(S) Test Script Recorder. Вы нажимаете кнопку Start, проходите сценарий в браузере, и... получаете гору запросов к google-analytics.comfonts.gstatic.com и прочему мусору. А главное — получаете жестко зашитые ID сессий или токены, которые на втором запуске превращают тест в тыкву.

Мой подход к созданию чистого скрипта (Best Practice):

  1. Transaction Controller. Каждый бизнес‑шаг (Логин, Поиск, Оплата) — отдельный контроллер. Это дает нам время отклика именно бизнес‑операции, а не кучки из 50 ресурсов.

  2. HTTP Header Manager. Никогда не ленитесь его настраивать. Без корректного Accept-Encoding: gzip вы будете грузить сеть и получать завышенное время ответа на статике.

  3. Регулярки и JSON Extractor. Вот где собака зарыта. Почти любое современное приложение шлет в ответе authenticity_tokenrequestVerificationToken или SessionId в куках.

Приведу простой пример обработки ответа в JMeter. Допустим, после логина сервер возвращает JSON с токеном, который нужно вставить в заголовок X-Auth-Token для всех следующих запросов.

// Это не код Java для выполнения, это пример настройки компонента JSR223 PostProcessor (Groovy)
// Я предпочитаю Groovy, он шустрее BeanShell и меньше утилизирует CPU

import groovy.json.JsonSlurper;

def response = prev.getResponseDataAsString();
def json = new JsonSlurper().parseText(response);
def token = json.data.authToken;

// Кладем токен в переменные JMeter
vars.put("AUTH_TOKEN", token);

// Логируем, чтобы при отладке не гадать — вытащилось или нет
log.info("Token extracted: " + token);

Почему это важно? В одном из проектов коллеги жаловались, что JMeter «глючит» — мол, проходит только один пользователь из десяти. Оказалось, что при разборе ответа через стандартный Boundary Extractor (по левой и правой границе) в ответе внезапно появлялся пробел в JSON из‑за особенностей форматирования бэкенда.

Регулярка "authToken":"(.*?)"ломалась, и 90% запросов шли без токена, получая 403. Деталь, которая стоила нескольких часов дебага. Поэтому — только JSON Extractor или Groovy.

Проведение нагрузочного теста: думаем как прод

Включать нагрузку с ноутбука через Wi‑Fi в кафе — это не совсем про тестирование (хотя почему и нет). Чтобы увидеть реальное поведение системы, нужно соблюсти несколько суровых правил.

Распределенный тест (Master‑Slave).Одна машина с Windows/Mac (мастер) управляет, несколько голых Linux‑серверов (слейвы) генерируют трафик. Почему Linux? Потому что там почти нет ограничений на количество ephemeral ports по умолчанию (они есть, но легче тюнятся через sysctl), по сравнению с Windows, и сетевая подсистема работает стабильнее.

Рис. 1 Архитектура распределенного нагрузочного тестирования с Apache JMeter

Рис. 1 Архитектура распределенного нагрузочного тестирования с Apache JMeter

На схеме показана классическая архитектура распределённого нагрузочного тестирования. С рабочего места инженера (ноутбук или десктоп) запускается Мастер JMeter — это управляющий узел, который содержит сценарий теста и раздаёт команды. Сам он трафик не генерирует. Реальную нагрузку создают Slave‑узлы — один или несколько выделенных серверов, обычно под Linux. Мастер синхронизирует их запуск и собирает агрегированные результаты.

Параллельно со стендом нагрузки работает мониторинг хоста (CPU, RAM, сеть), данные с которого также стекаются мастеру для последующей корреляции с временами отклика. Сами Slave‑узлы отправляют HTTPS‑запросы на целевой сервис, расположенный за балансировщиком. А тот, в свою очередь, взаимодействует с базой данных или кэшем. Такой подход позволяет не только проверить производительность приложения, но и увидеть, где именно находится узкое место: в самом приложении, на сетевом уровне или в инфраструктуре данных.

Профиль нагрузки — это не прямая линия вверх.
В реальной жизни нагрузка похожа на морские волны. Я всегда использую несколько плагинов:

  • Concurrency Thread Group (вместо стандартной) для удобного управления временем выхода на плато.

  • Throughput Shaping Timer — чтобы эмулировать не просто «100 потоков», а именно «500 запросов в секунду». Это критично для тестирования брокеров сообщений или API Gateway, которые могут начать шейпить трафик.

Анализ результатов: почему Average вводит в заблуждение?

Самое странное, что можно сделать — это открыть Summary Report и посмотреть в столбец Average (Среднее время).

Я видел отчеты, где писали: «Среднее время ответа 120 мс, всё хорошо». Потом выяснялось, что 99% запросов отрабатывали за 30 мс, а оставшийся 1% — за 12 000 мс (12 секунд!). Из‑за усреднения эти 12 секунд превратились в «приемлемые 120 мс». Пользователи при этом плевались и слали гневные тикеты.

На что можно полагаться:

  1. Response Time Graph по процентилям (через плагин jp@gc). Нас интересует p90, p95, p99. Если p90 = 30 мс, а p99 = 5 секунд — у нас проблема с долгим хвостом (GC pause или реконнект к БД).

  2. Transactions per Second (TPS). Ищем точку насыщения. Момент, когда добавляем виртуальных пользователей, а количество обработанных запросов в секунду перестает расти или падает — это и есть предел производительности текущего железа/конфигурации.

  3. Latency vs Connect Time. Если Connect Time высокий, проблема на сетевом уровне или в рукопожатии TLS. Если Latency высокая при низком Connect Time — копаем приложение.

Генерация HTML‑отчётов: зачем платить за BlazeMeter?

Многие до сих пор делают скриншоты графиков из GUI или, что еще хуже, пытаются рисовать графики в Excel, экспортируя сырой .jtl. Хотя в JMeter уже несколько лет есть штатная фича генерации Dashboard Report.

После прогона теста в CLI у вас есть .jtl файл. Даже если он весит 10 ГБ (что бывает), одной командой вы получаете полноценный дашборд, который не стыдно отправить заказчику:

jmeter -g /path/to/result.jtl -o /path/to/report/folder

Открываете index.html и видите:

  • APDEX (индекс удовлетворенности пользователей).

  • Тепловую карту времени отклика.

  • Топ ошибок по кодам ответа.

Совет: Если отчет кажется вам скучным, поднимите флаг jmeter.reportgenerator.overall_granularity=1000 в user.properties, чтобы сгладить пиковые выбросы на графиках и сделать картину чище.

Историческая справка: Как NASA «уронило» марсоход из‑за отсутствия нагрузочного теста

Марсоход Spirit попал в петлю перезагрузок из‑за проблемы с флэш‑памятью

В январе 2004 года, через 18 солов после посадки на Марс, марсоход NASA Spirit перестал нормально отвечать на команды и попал в бесконечную петлю перезагрузок.

Инженеры выяснили, что причина — в файловой системе флэш‑памяти (256 МБ). Из‑за большого количества накопившихся файлов (включая служебные логи, данные калибровки и другие записи, частично накопленные ещё во время перелёта) при попытке смонтировать файловую систему или работать с ней расходовалось слишком много оперативной памяти (RAM). Это приводило к ошибке, перезагрузке и повторению цикла.

Почему это произошло? На Земле тестирование проводилось в «тепличных» условиях и в основном проверяло функциональность. Никто не смоделировал реальную длительную эксплуатацию с накоплением сотен и тысяч файлов при ограниченных ресурсах. Когда ровер начал активно работать — создавать новые файлы во время сеансов связи, движения и научных измерений, — проявился недостаток robustness (устойчивости) файловой системы.

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

NASA удалось спасти миссию: ровер перевели в «crippled mode» (работа без использования флэш‑памяти), удалили тысячи ненужных файлов, а позже полностью переформатировали флэш. После этого Spirit продолжил работу и в итоге проработал более 6 лет (до 2010 года).

Урок для тестирования

Эта история отлично иллюстрирует цену нагрузочного и стресс‑тестирования. Один короткий сеанс связи — всё работает. Тысячи операций с накоплением логов и файлов в условиях ограниченной RAM и флэш — система падает в петлю.

Инструменты вроде JMeter или специализированных тестов для embedded‑систем помогают заранее выявлять такие boundary‑кейсы: длительную нагрузку записи/чтения, рост количества файлов, утечки ресурсов и поведение при приближении к пределам памяти.

Заключение: нагрузочное тестирование — это не QA, это инженерия хаоса

Разбор работы с JMeter — это не заучивание горячих клавиш. Это тренировка системного мышления. Умение спроектировать профиль нагрузки, вытащить токен, понять процентиль и объяснить разработчикам, почему их «оптимизация» запроса привела к росту времени ответа в хвосте.

Плохой специалист нажимает зеленую кнопку Play и смотрит на среднее время. Хороший — строит распределенный кластер, имитирует смешанную нагрузку и находит узкое место за неделю до релиза, а не в 3 часа ночи после него.

Если этот разбор показался вам полезным и вы хотите разобраться в практиках команд, которые держат многомиллионный RPS, приглашаю вас на открытые уроки курса «Нагрузочное тестирование» в OTUS. На уроках мы научимся работать с JMeter, разберем типовые ошибки при анализе .jtl логов и заложим фундамент, чтобы вы могли уверенно отвечать на вопросы о производительности на собеседованиях.

28 апреля в 20:00 — «Первый нагрузочный тест в Apache JMeter». Записаться

19 мая в 20:00 — «Навыки нагрузочного тестирования и их роль в развитии инженера». Записаться

Уроки бесплатные, нужно только зарегистрироваться.