Библиотека Go (Golang) разработчика

@golang_lib
🛑 Graceful Shutdown: Хватит обрывать запросы при деплое Знакомая ситуация: вы катите новую версию микросервиса в Kubernetes, и в этот момент графики в Grafana на пару секунд краснеют от 502/503 ошибок. А потом всё снова хорошо. Что произошло? Оркестратор убил старый под, а ваш Go-сервис моментально схлопнулся, оборвав на полуслове десятки текущих HTTP-запросов, сломав пару транзакций к базе и бросив недокачанные файлы. Как это работает в здоровом проде? Когда Kubernetes хочет обновить под, он не стреляет ему в голову сразу. Он посылает вежливый сигнал SIGTERM и дает время (обычно 30 секунд), чтобы собрать вещи. Мы должны перехватить этот сигнал и сказать нашему HTTP-серверу: "Новые запросы не принимай, а те, что уже в работе - спокойно доделывай". Как это написать: Забудьте про ручное создание make(chan os.Signal). Используйте signal.NotifyContext. func main() { // 1. Создаем контекст, который отменится при SIGINT (Ctrl+C) или SIGTERM (Docker/K8s) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() srv := &http.Server{Addr: ":8080", Handler: mux} // 2. Запускаем сервер в отдельной горутине! go func() { // http.ErrServerClosed возвращается при успешном Shutdown, это не ошибка if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Fatalf("Критическая ошибка сервера: %v", err) } }() // 3. Блокируемся и ждем сигнала от ОС <-ctx.Done() log.Println("Получен сигнал завершения. Тушим свет...") // 4. Создаем контекст с таймаутом для Shutdown shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // 5. Плавно останавливаем сервер (ждет завершения текущих хендлеров) if err := srv.Shutdown(shutdownCtx); err != nil { log.Printf("Сервер не смог остановиться плавно: %v", err) } // 6. Здесь закрываем коннекты к БД, RabbitMQ, сбрасываем кэши в Redis // db.Close() log.Println("Сервер успешно завершил работу.") } 🔥 Нюансы для Senior-ов: • Обязательно ставьте таймаут на Shutdown(). Если клиент с медленным интернетом качает от вас гигабайтный файл, srv.Shutdown будет ждать его вечно. В итоге K8s устанет ждать свои 30 секунд и жестко убьет под через SIGKILL (kill -9). Контролируйте таймаут сами (Шаг 4). • Порядок важен. Сначала останавливаем HTTP-сервер (чтобы перестали прилетать новые задачи), и только потом закрываем пул соединений с БД. Если сделать наоборот, текущие HTTP-запросы упадут с ошибкой sql: database is closed. #golang #architecture #kubernetes #bestpractices #devops 👉 @golang_lib
Если у вас установлено приложение,
вы можете сразу перейти в канал