Знакомы ли с профилировщиками
Что проверяют
Умеете ли вы искать узкое место по данным, а не по интуиции, и знаете ли встроенный инструментарий Go. Следом обычно просят рассказать случай: что тормозило, какой профиль вы сняли и что в нём увидели.
Как отвечать
Основа это pprof, он есть в стандартной библиотеке:
- в сервисе:
import _ "net/http/pprof"регистрирует обработчики/debug/pprof/вhttp.DefaultServeMux. Со своим роутером их подключают явно, а порт держат внутренним; - в тестах:
go test -bench . -cpuprofile cpu.out -memprofile mem.out, для произвольного кода естьruntime/pprof; - анализ:
go tool pprof -http=:8080 cpu.outоткрывает веб-интерфейс с графом вызовов и flame graph. Вtopразличайтеflat(время в самой функции) иcum(вместе с вызванными).
Назовите виды профилей и когда какой нужен:
- CPU: где процессор тратит время, через HTTP по умолчанию снимается 30 секунд;
- heap и allocs: занятая память и все аллокации, помогают найти лишние выделения и нагрузку на GC;
- goroutine: где стоят горутины, первое место для поиска их утечек;
- block и mutex: ожидание на каналах и блокировках. Включаются отдельно через
runtime.SetBlockProfileRateиruntime.SetMutexProfileFraction.
Для задержек планировщика и пауз GC есть go tool trace. Плюсом будет PGO: начиная с Go 1.21 компилятор сам берёт CPU-профиль из файла default.pgo в каталоге пакета main. В проде профили часто собирают непрерывно, через Pyroscope или Parca.
Где спотыкаются
Ищут в CPU-профиле, почему запрос долго ждёт. Ожидание сети и блокировок процессор не тратит, тут нужны block, mutex или trace.
Пишут import "net/http/pprof" без _ и больше ничего из пакета не используют. Такой код не компилируется из-за неиспользуемого импорта.
Открывают /debug/pprof/ наружу. Профили раскрывают устройство сервиса, а любой желающий может запускать их снятие и нагружать прод.