본문 바로가기
Computer language and framework/GO

[GO] graceful shutdown 이란?

by WhiteGoblin 2023. 2. 20.
반응형

 

또 면접에서 모르는 사안이 나왔는데 너무 기초적인 부분이지만 내가 아예 알지 못해서 설명하지 못했다. 

 

다시 한번 반성하면서 작성해보겠다. 

 

우선 여러 조사를 거친 결과 리눅스 kill 시그널에 대해서 알아 보는것이 좋다. 

 

* 리눅스 시그널이란? 

 

- 프로세스에 어떤 이벤트의 발생을 알리기 위해 전달되는 소프트웨어 인터럽트

- 흔히 우리가 어떠한 프로그램을 강제 종료 시키기 위해서 ctrl + c 를 입력해서 강제종료 시킬 때 보내는 시그널을 생각하면 편하다. 

 

이 중에서 수많은 시그널중 우리가 주목해야 하는것이 SIGTERM, SIGKILL 이다.

 

이 중 SIGKILL 의 경우 해당 프로세스가 리소스 정리나 다른 것들을 하는 것을 수행하는것과 상관 없이 바로 프로세스를 죽여서 문제가 발생하게 된다. 

 

하지만 SIGTERM 의 경우 이와 반대로 자원들과 마무리할 시간을 주고 이에 따라서 자원을 정리하는 말 그대로 graceful shutdown 이 이루어진다. 

 

유명한 삽화가 하나 있어서 가지고 오자면 

 

 

* Graceful shutdown 이란?

 

- 앞서 말한 것 처럼 프로그램이 OS 혹은 다른 소프트웨어로 인해 종료 될때 해당 task 를 안전하게 실행해서 완료 하고 process 와 connection 을 닫는 것을 의미한다. 

- 반대 되는 말로는 hard shutdown 이 있다. 

 

* Graceful shutdown 예제 

 

구현을 위해서는 우선 무엇을 수행할지를 정해야 하는데 

 

1. 실행중인 프로세스가 다 수행되게 할것인지

2.  termination signal 을 어떻게 전송할지 이다. 

 

echo 에서는 해당 부분에 대한 코드를 제공해주고 있는데 

 

package main

import (
	"context"
	"net/http"
	"os"
	"os/signal"
	"time"

	"github.com/labstack/echo/v4"
	"github.com/labstack/gommon/log"
)

func main() {
	// Setup
	e := echo.New()
	e.Logger.SetLevel(log.INFO)
	e.GET("/", func(c echo.Context) error {
		time.Sleep(5 * time.Second)
		return c.JSON(http.StatusOK, "OK")
	})

	// Start server
	go func() {
		if err := e.Start(":1323"); err != nil && err != http.ErrServerClosed {
			e.Logger.Fatal("shutting down the server")
		}
	}()

	// Wait for interrupt signal to gracefully shutdown the server with a timeout of 10 seconds. 
	// Use a buffered channel to avoid missing signals as recommended for signal.Notify
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, os.Interrupt)
	<-quit
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	if err := e.Shutdown(ctx); err != nil {
		e.Logger.Fatal(err)
	}
}

[자료 출처]

https://echo.labstack.com/cookbook/graceful-shutdown/

 

Echo - High performance, minimalist Go web framework

Echo is a high performance, extensible, minimalist web framework for Go (Golang).

echo.labstack.com

위에서 제시한 두가지 조건을 정확하게 지켜내는 코드 임을 확인 할 수 있다. 

 

go routine 을 통해서 서버를 시작하고 os interrupt 를 통해서 들어오는 signal 을 받아서 10 초 의 타임아웃을 가지는 graceful shutdown 을 이루어 냅니다. 

 

이 글 하나로 다 정확히 파악한 것은 아니지만 차후 kubernetes 에서 graceful shutdown 을 하는 방안에 대해서 쓴 글들이 많기에 이와 맞물려서 확인 하면 보다 거시적인 이해를 추구 할 수 있을거 같습니다. 

 

https://peterica.tistory.com/184

 

[Kubernetes] Pod의 종료 사이클과 Graceful Shutdown

ㅁ 개요 Kubernetes환경에서 graceful shutdown의 적용방법을 공부하면서 Kubernetes환경에서 오케스트레이션 작업 중 Pod가 종료되는 과정이 많다. 로드밸런싱 역할을 하는 Service와 속해 있는 Pod 들이 종료

peterica.tistory.com

https://peterica.tistory.com/183

 

[Kubernetes] Kubernetes환경에서 graceful shutdown이란

ㅁ 개요 ㅇ Kubernetes가 배포 절차를 수행해 주지만 컨테이너 안에서 Spring Boot 애플리케이션의 정상적인 종료를 위해서는 Graceful shutdown이 필요하다. ㅇ 트래픽에 따라 AutoScaling 되면서 502error가 발

peterica.tistory.com

 

위 두 글들이 매우 자세하고 알기 쉽게 설명 해주셨습니다. 

 

다시 한번 감사 드리며 이 글은 여기서 멈추겠습니다~

반응형