그레이스풀 셧다운은 데이터 손실을 방지하고, 사용자 경험을 유지하기 위해 서버와 애플리케이션을 안전하게 종료하는 과정입니다. 이 과정은 시스템 자원을 올바르게 해제하고, 갑작스러운 종료로 인한 시스템 오류를 최소화합니다. 또한, 로그 및 감사 추적을 통해 시스템의 성능 분석과 문제 해결에 도움을 줍니다.
서버나 애플리케이션에서 여러 가지 문제가 발생할 수 있습니다. 주요 문제점은 다음과 같습니다
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "안녕하세요, Go 서버에 오신 것을 환영합니다!")
})
fmt.Println("서버가 8080 포트에서 시작됩니다.")
http.ListenAndServe(":8080", nil)
}
이 코드는 8080 포트에서 실행되는 간단한 HTTP 서버를 만듭니다. 클라이언트가 서버에 연결할 때마다, 서버는 "안녕하세요, Go 서버에 오신 것을 환영합니다!"라는 메시지를 응답합니다.
그레이스풀 셧다운은 서버를 안전하게 종료하는 방법으로, 진행 중인 모든 요청을 마무리한 후 서버를 종료합니다. 이를 통해 갑작스러운 서버 종료로 인한 데이터 손실이나 클라이언트 오류를 방지할 수 있습니다.
그레이스풀 셧다운 구현 방법
1. 컨텍스트와 취소 함수 사용: context 패키지를 사용하여 셧다운 시그널을 관리합니다.
2. HTTP 서버 커스터마이징: http.Server 구조체를 사용하여 서버를 구성하고, 셧다운 시그널에 대응할 수 있게 합니다.
3. OS 시그널 감지: OS로부터 셧다운 요청을 감지합니다 (예: CTRL+C).
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
srv := &http.Server{Addr: ":8080"}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "안녕하세요, Go 서버에 오신 것을 환영합니다!")
})
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("HTTP 서버 에러: %s\n", err)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
fmt.Println("서버가 종료되고 있습니다...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
fmt.Printf("서버 셧다운 에러: %s\n", err)
}
fmt.Println("서버가 안전하게 종료되었습니다.")
// 서버가 완전히 종료될 때까지 대기
<-ctx.Done()
fmt.Println("서버 종료 완료")
이 코드는 Go 언어를 사용하여 HTTP 서버를 구축하고, OS 시그널을 감지하여 서버를 안전하게 종료하는 그레이스풀 셧다운을 구현합니다. 서버는 기본적으로 8080 포트에서 시작되며, CTRL+C 같은 중단 시그널을 받으면, 정해진 시간 내에 모든 처리 중인 요청을 마무리하고 서버를 종료합니다.
그레이스풀 셧다운을 통해 서버를 안전하게 종료하는것은 실제 웹 서비스나 API 서버 개발에 있어 매우 중요한 부분입니다. 그리고 어렵지도 않기에 기본적으로 사용하는것을 적극 권장합니다.