События
Серии событий
Нагрузочная проверка обработчика: количество, скорость, потолки и обратная связь по фактической скорости.
На этой странице · 7
Серия — это N доставок одного события с заданной скоростью. Она отвечает на вопрос, который на одиночных «Тестах» не проверить: выдержит ли обработчик реальный поток и что случится, когда он перестанет успевать.
apistend trigger ONCRMDEALUPDATE --count 500 --rate 100 --watch
Тот же движок обслуживает сценарии на экране «Вебхуки»: у сценария просто заполнен идентификатор сценария, а параметры те же — событие, сколько отправить, с какой скоростью и какую долю сбоев имитировать.
Параметры
Флаги серии
Задать можно и одно значение из двух: --count без --rate отправит всё
как можно ровнее за секунду, --rate без --count — одну секунду работы
на этой скорости.
--error-rate не портит ответ приложения, а не отправляет событие вовсе:
доставка создаётся, видна в журнале и сразу получает исход «сбой отправки».
Так проверяется ветка обработки ошибок и лестница повторов сервиса.
Потолки
Серия обрезается по потолкам сервера, и об обрезке говорят вслух:
$ apistend trigger ONCRMDEALUPDATE --count 60 --rate 900
> Серия ONCRMDEALUPDATE: 60 событий по 500 соб/с ≈ 1 с
> Получатель: /bitrix/deal
! скорость ограничена до 500 соб/с
Значения потолков задаются переменными окружения стенда — BURST_MAX_RATE,
BURST_MAX_COUNT и BURST_MAX_CONCURRENT — и видны в ответе GET /api/bursts,
так что смотреть их надо у своего стенда, а не в этом тексте. В .env.example
они выставлены в 500 событий в секунду, 100 000 событий на серию и 3
одновременные серии на песочницу.
Отказы разведены по причинам, потому что чинятся по-разному:
Серия на локальный получатель без агента не запускается намеренно: иначе она насыпала бы тысячи строк в очередь и ничего не проверила.
Прогресс и фактическая скорость
С --watch CLI опрашивает прогресс дважды в секунду и перерисовывает одну строку:
> Серия ONCRMDEALUPDATE: 300 событий по 100 соб/с ≈ 3 с
> Получатель: /bitrix/deal
50 % 150/300 99 соб/с из 100
> Серия завершена: отправлено 300 из 300 · успешно 300 · ошибок 0
300 из 300 событий · 98 соб/с фактически
Показывается фактическая скорость, а не заказанная. Считается она по фазе отправки: после последнего события серия ещё ждёт ответы, и если бы это ожидание попало в знаменатель, скорость оказалась бы заниженной.
«Приложение не успевает»
Сервер не наливает в сокет всё, что положено по расписанию. Он следит за числом доставок, отданных агенту и оставшихся без ответа. Потолок — удвоенная заказанная скорость, но не меньше 20 доставок. Когда потолок достигнут, такт пропускается, а строка прогресса это показывает:
75 % 375/500 21 соб/с из 50 приложение не успевает
...
> Серия завершена: отправлено 500 из 500 · успешно 500 · ошибок 0
500 из 500 событий · 20 соб/с фактически · приложение не успевало 15.2 с
Это и есть главный результат нагрузочной проверки: заказано 50 событий в секунду, приложение вытянуло 20. Без притормаживания замер показывал бы скорость записи в сокет, а не скорость обработки.
Секунды в итоге — это пропущенные такты, умноженные на длину такта (сто миллисекунд), то есть сколько времени серия простояла в ожидании вашего приложения.
Локальная параллельность тоже потолок
Агент по умолчанию делает не больше 16 одновременных вызовов приложения
(--concurrency). Если обработчик отвечает за секунду, выше 16 событий в секунду
поток не поднимется, сколько ни заказывай, — и серия честно об этом скажет.
Итог серии
Когда отправка кончилась, серия переходит в фазу ожидания ответов: ждёт таймаут сервиса плюс две секунды запаса и только потом подводит итог. Без этой фазы в сводке недосчитывалось бы успешных доставок — приложение просто не успевало ответить на последние.
Итоговая строка собирается из фактов: сколько отправлено из заказанного, какая
получилась скорость, сколько доставок осталось без ответа в срок и сколько
времени приложение не успевало. Успешными считаются доставки в состоянии
succeeded, неуспешными — failed, no_response и dropped.
Остановка вручную (кнопка «Стоп» на экране «Вебхуки») ставит в итог пометку «Остановлено вручную» и не ждёт таймаут: подвисшие доставки всё равно подберёт уборщик планировщика.
Состояние interrupted
Расписание серий живёт в памяти процесса API — своего таймера у каждой серии нет,
такт общий на все. Перезапуск сервера это состояние теряет, и притворяться,
что серия продолжается, стенд не может. Поэтому при старте все серии, оставшиеся
в состоянии running, честно помечаются interrupted с пометкой «Прервана
перезапуском сервера», а сценарии, которые их запускали, возвращаются в ready.
Итоговых чисел у такой серии нет: сколько успело уйти, видно по журналу доставок её событий. Прерванная серия не возобновляется — запустите её заново.
Подводные камни
- Событие серии — то же, что и одиночное. Порядковый номер меняет идентификаторы в теле, но структура одна; уникальные данные для каждой доставки серия не выдумывает.
- Серия не запускается поверх идущего сценария. Второй запуск того же сценария отвечает 409: две серии с одним идентификатором писали бы прогресс вдвоём, а полоса на экране показывала бы одну.
- Удаление вебхука посреди серии останавливает её с пометкой «Вебхук удалён во время серии», а его доставки уходят вместе с ним каскадом.
- Bitrix24 в серии с
--error-rateне повторяет ничего. Все имитированные сбои сразу терминальны — у сервиса нет повторов.