Мелкий сервис на стейджинге странно тупил: запросы шли, но медленно. Мониторинг показывал один полностью загруженный поток, при этом общая нагрузка на машину — копейки. Обычно такой паттерн означает одно: весь процесс упёрся в код, который тупо не параллелится.
Прогнал perf top — и почти всё время тратилось внутри стандартной библиотеки на сериализацию JSON. Переделали на easyjson c предгенерацией, профиль выровнялся, хвост latency упал вдвое.
Мораль простая: если что-то постоянно тормозит — посмотри, как именно работает нижний слой. Часто дело не там, куда сначала смотришь.
ulimit — самая недооценённая настройка
2 апреля · 3 мин
Маленький параметр, но ломает поведение надёжнее, чем большинство "оптимизаций". Особенно на сервисах, которые держат много одновременных подключений: дефолтный лимит открытых файловых дескрипторов в 1024 заканчивается на ровном месте, и сервис начинает выбрасывать понятную только при вскрытии ошибку too many open files.
Поднимаем через systemd-юнит: LimitNOFILE=65536. Две минуты работы, плюс к стабильности под пиками.
Nagle и TCP_NODELAY: маленький флажок, большая разница
23 марта · 2 мин
По умолчанию TCP собирает мелкие записи в один пакет — алгоритм Nagle. На пропускной способности это выигрыш, но для latency-чувствительных протоколов (RPC, интерактив) дополнительные 40 мс задержки никому не нужны.
Лечится либо выставлением TCP_NODELAY на сокете, либо встроенной опцией фреймворка. В gRPC, например, это по умолчанию. В более старых клиентах — нужно включать руками. Простое изменение, а хвост latency иногда падает на порядок.
Sysctl, который обычно забывают
11 марта · 2 мин
Дефолтный vm.dirty_ratio в Linux рассчитан на машины без SSD и без современной нагрузки. В результате при массовом write-bursts система набирает в памяти гигабайты грязных страниц, а потом разом пытается их сбросить — и латентность встаёт колом.
Поднимаем vm.dirty_background_ratio, уменьшаем vm.dirty_ratio. Три строки в /etc/sysctl.d/, плюс sysctl -p. Местами даёт заметный эффект на запись в БД и на I/O-heavy сервисы.
Маленький трюк с bash-скриптами
28 февраля · 1 мин
Если скрипт запускается по SSH и фоновый процесс там нужен на долгий срок — nohup и & иногда не спасают: сессия рвётся, дочерний процесс цепляется за неё и умирает. Надёжнее через systemd-run --unit=name.
Плюс автоматически появляется управление через systemctl, и логи пишутся в journal. Решение, которое стоит помнить.