11 AI Prompts to Hunt Goroutine Leaks, Tune gRPC and Read pprof Like a Go SRE

Go без тормозов: 11 промтов для конкурентности, gRPC и профилирования высоконагруженных сервисов

Go создавался в Google как язык для сетевых сервисов, которые должны держать нагрузку и не падать под ней. Горутины, каналы, сборщик мусора с низкими паузами, встроенный pprof — всё это есть в стандартной библиотеке и работает без сторонних фреймворков. Проблема в другом: даже аккуратный код на Go легко превращается в источник утечек горутин, гонок данных и неожиданных аллокаций. По данным официальной документации Go, net/http/pprof и runtime/pprof дают доступ к CPU-, heap-, goroutine-, mutex- и block-профилям, но мало кто открывает их регулярно.

Эта подборка — про то, как использовать LLM как второго инженера рядом с вами. Промты ниже покрывают полный цикл: проектирование конкурентных паттернов, генерация gRPC-сервисов, поиск утечек горутин, чтение pprof-профилей, оптимизация аллокаций и безопасный рефакторинг горячего пути. Каждый промт — копипаст-реди, с пояснением задачи и примером. Ссылки на первоисточники (go.dev, pkg.go.dev, grpc.io) прилагаются, чтобы вы могли проверить каждое утверждение.

1. Генерация конкурентного паттерна под конкретную задачу

Задача: когда нужно выбрать между worker pool, fan-out/fan-in, errgroup или pipeline — и получить сразу рабочий каркас.

Ты senior Go-инженер. Мне нужно обработать N задач с ограничением параллелизма.
Контекст:
- Go 1.22+, доступны context, errgroup (golang.org/x/sync/errgroup)
- Задачи: <опиши, например, HTTP-вызовы с таймаутом 2s>
- Требования: отмена по context, сбор первой ошибки, ограничение воркеров
Выдай: 1) выбор паттерна и почему, 2) полный код с комментариями,
3) как тестировать через go test -race, 4) подводные камни.

Пример использования: обработка 10 000 URL с лимитом 50 одновременных запросов. Модель предложит worker pool на канале задач + errgroup.WithContext. Проверяйте результат командой go test -race ./... — гонки данных ловятся именно так.

2. Аудит кода на утечки горутин

Задача: найти горутины, которые никогда не завершатся.

Проанализируй код ниже на утечки горутин и блокировки.
Ищи: горутины без выхода, запись в небуферизованный канал без читателя,
отсутствие select с ctx.Done(), забытый cancel().
Формат ответа: таблица

| строка | проблема | почему утечка | фикс |
Затем покажи исправленную версию.

Пример: функция, которая пишет в канал results после возврата из функции — классика. Правильный фикс: буферизованный канал или select с ctx.Done(). Встроенный go test с goleak (github.com/uber-go/goleak) в TestMain ловит такие утечки автоматически.

3. Проектирование gRPC-сервиса с .proto и интерсепторами

Задача: сгенерировать proto-файл и серверную обвязку с логированием, метриками и таймаутами.

Спроектируй gRPC-сервис на Go (grpc-go) для <домен>.
Дай: 1) .proto с proto3, полями и RPC-методами;
2) сервер с unary-интерсепторами: логирование, recovery, таймаут;
3) клиент с retry и keepalive;
4) команду protoc (protoc-gen-go, protoc-gen-go-grpc).
Учти context propagation и deadline.

Пример команды генерации: protoc --go_out=. --go-grpc_out=. proto/service.proto. Интерсепторы регистрируются через grpc.ChainUnaryInterceptor. Официальные примеры — на github.com/grpc/grpc-go.

4. Поиск узкого места по CPU-профилю pprof

Задача: превратить profile в список конкретных мест для оптимизации.

Вот вывод go tool pprof -top (вставь текст).
Объясни: 1) какие функции — горячие и почему;
2) что можно исправить без изменения архитектуры;
3) какие аллокации убрать;
4) как проверить эффект через benchstat.
Дай конкретные патчи.

Пример: если в топе runtime.mallocgc и strings.Split — вы аллоцируете на каждом запросе. Фикс: strings.Builder или sync.Pool. Документация: pkg.go.dev/net/http/pprof.

5. Чтение heap-профиля и борьба с аллокациями

Задача: понять, куда уходит память и почему GC работает часто.

Покажи, как снять heap-профиль в работающем сервисе:
1) через net/http/pprof (debug=1 и debug=0);
2) сравнить два профиля: go tool pprof -base old.prof new.prof;
3) интерпретировать inuse_space vs alloc_space;
4) предложить 5 типовых оптимизаций для Go 1.22.

Пример: go tool pprof -http=:8080 http://localhost:6060/debug/pprof/heap. Разница inuse_space (живая память) и alloc_space (всего аллоцировано) критична: первая показывает утечки, вторая — давление на GC.

6. Настройка GOGC и GOMEMLIMIT под нагрузку

Задача: подобрать параметры сборщика мусора без перезапуска сервиса.

У меня сервис на Go с нагрузкой <RPS>, heap ~<размер>, latency SLA <p99>.
Объясни влияние GOGC и GOMEMLIMIT (Go 1.19+).
Дай: 1) как выставить через runtime/debug.SetMemoryLimit;
2) как метрики runtime.MemStats читать в Prometheus;
3) как проверить эффект через нагрузочный тест.

Пример: GOGC=100 (значение по умолчанию) означает, что heap удваивается перед сборкой. GOMEMLIMIT=4GiB заставляет GC работать агрессивнее при приближении к лимиту. Официальный гайд: go.dev/doc/gc-guide.

7. Генерация нагрузочного теста и бенчмарка

Задача: получить воспроизводимый бенчмарк с реалистичным профилем.

Напиши Go-бенчмарк для функции <имя>.
Требования: b.ReportAllocs(), b.ResetTimer(), table-driven cases,
запуск через go test -bench=. -benchmem -count=10.
Дополнительно — пример запуска ghz или k6 для gRPC-эндпоинта.

Пример: go test -bench=BenchmarkHandler -benchmem -cpuprofile=cpu.prof. Для gRPC есть ghz — реальный инструмент с открытым исходником.

8. Диагностика гонок данных по race detector

Задача: разобрать вывод -race и не сломать логику фиксом.

Вот вывод go test -race (вставь). Объясни:
1) какие две горутины конфликтуют и на какой переменной;
2) почему это гонка, а не ложное срабатывание;
3) предложи минимум 2 варианта фикса (mutex / atomic / channel) и trade-offs;
4) покажи патч.

Пример: race detector — часть тулчейна (go test -race), не сторонний плагин. Он ловит реальные обращения к памяти, но не заменяет проектирование.

9. Оптимизация горячего пути и escape analysis

Задача: понять, почему объект уходит в heap.

Покажи вывод go build -gcflags=-m (вставь фрагмент).
Объясни, какие переменные escaped to heap и почему.
Предложи изменения: передача по значению, уменьшение размера структуры,
избегание интерфейсов в горячем цикле.

Пример: go build -gcflags='-m -m' ./... печатает решения компилятора. Частая причина escape — возврат указателя на локальную переменную или передача в interface{}.

10. Рефакторинг с сохранением поведения

Задача: переписать код так, чтобы тесты остались зелёными.

Отрефактори <функция> для снижения аллокаций и упрощения.
Ограничения: публичный API не менять, тесты должны пройти без правок.
Дай: diff, объяснение каждого изменения, команду для проверки
(go test ./... -race -count=1).

Пример: замена fmt.Sprintf на strconv.AppendInt в горячем пути экономит аллокации. Проверяйте через benchstat до/после.

11. Генерация observability-обвязки

Задача: подключить метрики, трейсинг и профилирование в один сервис.

Покажи, как подключить к Go-сервису:
1) Prometheus (prometheus/client_golang);
2) OpenTelemetry (go.opentelemetry.io/otel);
3) net/http/pprof на отдельном порту;
4) health-check /healthz и /readyz.
Дай полный main.go и объясни, почему pprof не должен быть на публичном порту.

Пример: pprof на :6060 в отдельной internal-сети — стандартная практика. Публичный доступ к /debug/pprof — риск утечки информации и DoS.

Промт Что решает Ключевой инструмент
1 Паттерн конкурентности errgroup, context
2 Утечки горутин goleak
3 gRPC-сервис protoc, grpc-go
4 CPU-профиль pprof -top
5 Heap-профиль pprof -base
6 Настройка GC GOGC, GOMEMLIMIT
7 Нагрузка ghz, k6
8 Гонки go test -race
9 Escape analysis -gcflags=-m
10 Рефакторинг benchstat
11 Observability Prometheus, OTel

Что дальше

Промты не заменяют чтение исходников и профилирование на реальных данных. Используйте их как ускоритель: сначала получите каркас и гипотезы от модели, затем проверьте pprof, -race и бенчмарками. Официальные точки входа — go.dev/doc, pkg.go.dev/net/http/pprof, grpc.io/docs/languages/go. Если хотите системно закрыть темы конкурентности, gRPC и профилирования — начните с одного промта из списка на своём коде и доведите его до измеримого результата: latency p99, число аллокаций, размер heap. Такой цикл даёт больше, чем десяток прочитанных статей.

← All posts

Comments