Панель, которая тормозила из-за 57 асинхронных обработчиков
Внутренняя панель вела себя странно: открываешь одну страницу — и вся панель встаёт колом для всех вкладок, пока она не догрузится. Профилировать там особо нечего, и я пошёл читать. Нашлось три независимых причины и одна бонусная. Первая и главная: все 57 обработчиков были объявлены асинхронными, но ни один ничего не ждал асинхронно — внутри синхронные запросы к базе, вызовы докера, хождение по SSH и снятие дампа. Всё это выполнялось прямо в цикле событий, то есть один медленный запрос честно блокировал весь сервер. Лечится парадоксально: убрать асинхронность — тогда фреймворк уводит такие обработчики в пул потоков, и запросы наконец идут параллельно; заодно пришлось поднять размер пула соединений к базе, потому что до этого параллельность была фиктивной.
Вторая причина — опрос состояния сервисов по одному, включая отдельное SSH-подключение на каждый сервис на удалённых хостах. Свёл к одному пакетному запросу на хост под общим коротким кэшем, а SSH-хопы перевёл на переиспользование соединения вместо нового рукопожатия на каждый вызов. Третья — страница со списком таблиц считала точное количество строк по каждой таблице, то есть делала полный скан по всем сразу. Точный счёт оставил для небольших таблиц, для крупных перешёл на оценку планировщика. Бонусная: стили и иконки грузились с внешней CDN, и при её недоступности вкладка висела в загрузке уже после того, как разметка пришла — ассеты убрал внутрь.
Фактура
- 57 обработчиков с асинхронной сигнатурой и нулевым ожиданием внутри; всё синхронное исполнялось в цикле событий. Единственный по-настоящему асинхронный обработчик (поток событий) не трогал.
- Пул соединений к базе: 10 → 24, после того как запросы стали действительно параллельными.
- Опрос сервисов: 11 сервисов по одному, из них 6 — через отдельные SSH-подключения; стало по одному пакетному запросу на хост под кэшем в 10 секунд плюс мультиплексирование SSH.
- Список таблиц: точное количество строк до порога в 50 тысяч, выше — оценка планировщика; то же самое для постраничного просмотра записей.
- Внешняя CDN заменена локальными ассетами, политика безопасности контента при этом ужата до собственного источника.
- Проверено живым набором из 60 тестов против работающей панели.