[TIR] 2025.08.21(목)

2025. 8. 21. 16:44·Own/TIR(Today I Read)

Learn이라기에는 부족하고 그저 인지했을 뿐인 오늘의 TIR(Today I Read)

넘쳐나는 공부거리로 밀리는 블로그 포스트 대체방안... 일단 메모하고... 주말에 틈틈히 제대로 공부한다!


✏️ Go서버 메모리 프로파일링

로컬 환경에서 pprof 돌려본게 전부인 사람 여깄어요... 공부가 많이 필요해요.... 공부 1순위..

팀에서 공인된(?) 리팩토링 담당자라 지금 빨리 공부해서 써먹어야함

 

0. 즉시 조치: 메모리 증설(매우매우 임시방편)

1. 프로파일링 & 모니터링 메트릭 수집

- Grafana/Prometheus+pprof 조합

## Grafana로 확인
- [ ] 메모리 사용 패턴 (계단식? 선형? 급증?)
- [ ] 문제 발생 시간대 (특정 시간? 랜덤?)
- [ ] CPU와 상관관계 (CPU 높을 때 메모리도?)
- [ ] 네트워크 I/O와 상관관계 (API 호출?)
- [ ] Go 메트릭 있는지 (go_memstats_*, go_goroutines)

## pprof 수집 타이밍
- [ ] Grafana에서 메모리 상승 시작 시점
- [ ] 피크 시점
- [ ] OOM 직전

## 비교 분석
- [ ] 정상 시점 vs 문제 시점 pprof diff
- [ ] Grafana 패턴과 pprof 결과 매칭

2. gdb로 메모리 덤프 & 분석(ㅁㅊ.. gdb 시스템 해킹 이후로 오랜만)

3. docker로 서버 띄워서 컨테이너 내 메모리 사용량 모니터링 + 메모리 덤프 수집(pprof) -> 덤프 분석

4. 테스트 환경에서 포트포워딩 접근해서 pprof 모니터링 & 분석

5. pyroscope 같은 continous profiling 도구 (현실적으로 바로 도입하기에는 무리)

[패턴1: 계단식 증가]
메모리 그래프:
     │     ┌─────
     │  ┌──┘      
     │┌─┘         
    ─┘
    10시 11시 12시
    
의미: 특정 이벤트마다 메모리 증가
원인: 캐시, 맵, 슬라이스 무한 증가

[패턴2: 선형 증가]
메모리 그래프:
     │      /
     │    /
     │  /
    ─┘/
    10시 11시 12시
    
의미: 지속적으로 누수
원인: 고루틴 누수, 커넥션 미해제

[패턴3: 급증 후 유지]
메모리 그래프:
     │    ────
     │   │
     │───┘
    
의미: 대량 데이터 로드 후 미해제
원인: 대용량 쿼리 결과 캐싱

 

하다가 안고쳐지면 GC 튜닝까지 고려...흠.. 근데 이럴 경우까지 있나..

 

✏️ 고루틴 생명주기 규칙

1. main 함수가 종료되면, 모든 고루틴은 강제로 즉시 종료

- main 함수는 모든 고루틴의 '최상위 부모', 프로그램의 생명주기 자체 --> main이 끝나면 프로그램이 끝나므로 다른 모든 고루틴도 함께 사라짐

2. main 함수를 제외하고, 어떤 고루틴도 다른 고루틴을 직접적으로 종료시킬 수 없음

- 고루틴 A가 고루틴 B를 go 키워드로 실행시켰다고 해서, A가 B의 '부모'가 되는 특별한 관계가 생기는 것이 아님. A와 B는 그냥 독립적으로 실행되는 두 개의 동시 작업 단위일 뿐

- 따라서 고루틴 A가 먼저 끝나더라도, 고루틴 B는 자신의 작업이 끝날 때까지 계속 실행됨

예제)

package main

import (
	"fmt"
	"time"
)

func parent() {
	fmt.Println("Parent: Starting child goroutine...")
	
	// 자식 고루틴 시작
	go child()
	
	time.Sleep(2 * time.Second)
	fmt.Println("Parent: My job is done. I'm exiting.")
	// 여기서 parent() 함수는 종료되고, parent 고루틴은 사라집니다.
}

func child() {
	fmt.Println("  Child: I'm starting my eternal loop.")
	// 이 자식 고루틴은 1초마다 메시지를 출력하는 무한 루프를 돕니다.
	for i := 0; ; i++ {
		fmt.Printf("  Child: ...working... (%d)...\n", i)
		time.Sleep(1 * time.Second)
	}
}

func main() {
	parent()
	
	fmt.Println("Main: Parent has exited. Waiting for a bit to see what child does...")
	time.Sleep(5 * time.Second)
	fmt.Println("Main: Exiting.")
}

 

결과)

Parent: Starting child goroutine...
  Child: I'm starting my eternal loop.
  Child: ...working... (0)...
  Child: ...working... (1)...
Parent: My job is done. I'm exiting.
Main: Parent has exited. Waiting for a bit to see what child does...
  Child: ...working... (2)...
  Child: ...working... (3)...
  Child: ...working... (4)...
  Child: ...working... (5)...
  Child: ...working... (6)...
Main: Exiting.

결과를 보면, "Parent: My job is done." 이라는 메시지가 출력된 후에도 child 고루틴은 전혀 멈추지 않고 계속해서 작업을 수행하는 것을 볼 수 있다. parent 고루틴은 이미 사라졌지만 child는 그 사실을 전혀 알지 못하는데, 이 child가 바로 '좀비 고루틴'

--> 그래서 Context가 필요한 것! Context는 부모와 자식 고루틴 사이에 '작업 종료'라는 신호를 전달할 수 있는 유일한 표준적인 방법

만약 parent가 Context를 만들어서 child에게 전달하고, parent가 종료되기 직전에 그 Context를 cancel()했다면, child는 루프 안에서 ctx.Done() 채널을 확인하고 스스로 루프를 멈추고 안전하게 종료할 수 있었을 것!

 

✏️ Graceful Shutdown 중요성

main의 강제 종료에 의존하면 안 되는 이유

  1. 데이터 정합성 파괴
    • 만약 어떤 고루틴이 데이터베이스 트랜잭션을 막 시작해서 A 계좌에서 돈을 출금했는데, B 계좌에 입금하기 바로 그 찰나에 main이 종료된다면 어떻게 될까? 돈은 공중으로 사라지고 데이터는 영원히 깨진 상태로 남는다.
    • 파일을 쓰는 도중이었다면, 파일은 반만 쓰인 채로 손상됨.
  2. 진행 중인 작업 유실
    • 만약 고루틴이 메시지 큐에서 중요한 작업을 꺼내와 처리하는 중이었다면? 프로그램이 강제 종료되면 그 작업은 처리되지 않은 상태로 유실될 수 있음. 다음 실행 때 이 작업을 다시 처리할 수 있다는 보장이 없음.
  3. 외부 리소스 정리 불가
    • 작업 중에 임시 파일을 만들었거나, 외부 시스템에 잠금(lock)을 걸었다면 어떻게 될까? 강제 종료 시에는 이 리소스들을 정리하는 defer 구문이나 후처리 코드가 실행될 기회조차 없다. 임시 파일은 서버에 쓰레기로 남고, 외부 시스템의 잠금은 풀리지 않아 다른 프로세스에 장애를 일으킬 수 있다.
  4. 운영의 어려움
    • "서버를 정상적으로 종료합니다" 와 같은 마지막 로그를 남길 수 없음. 서버가 정상적으로 종료된 것인지, 아니면 알 수 없는 에러로 죽은(crash) 것인지 구분하기가 매우 어려워짐.

Graceful Shutdown의 역할

우리가 Context, WaitGroup, os.Signal을 이용해 구현하는 Graceful Shutdown은 바로 이 "시스템 종료" 버튼의 역할을 한다.

  1. signal.Notify: 운영체제가 "이제 그만 종료해줘 (SIGTERM)" 라고 보내는 신호를 정중하게 받는다.
  2. context.CancelFunc: 이 신호를 받으면, 모든 고루틴에게 "하던 일 마저 정리하고 퇴근 준비해" 라고 Context를 통해 알려준다.
  3. 고루틴의 정리 작업: 각 고루틴은 이 신호를 받고, DB 트랜잭션을 커밋하거나 롤백하고, 열었던 파일을 닫고, 마지막 로그를 남기는 등 뒷정리
  4. sync.WaitGroup: 모든 고루틴이 "저 퇴근 준비 다 됐습니다" 라고 보고할 때까지 기다림
  5. main 종료: 모든 것이 안전하게 정리된 것을 확인한 후에야 비로소 main 함수가 종료

 

✏️ 스테이블 코인

사실 카이아 스테이블 코인 해커톤에 나간다. 이와 관련해서 스테이블 코인에 관한 리서치들을 모조리 탐독하려고 노력중

텔레그램 글을 더 많이 읽고 있긴 한데... 일단 좋은 포필러스의 리서치 글들을 남겨본다.

 

https://4pillars.io/ko/articles/are-stablecoin-payments-a-threat-to-banks-and-card-networks

 

스테이블코인 결제: 은행과 카드 네트워크에게 위협인가?

스테이블코인은 전통 결제 시스템을 어떻게 바꿀까요?

4pillars.io

https://4pillars.io/ko/issues/what-are-the-advantages-of-krw-stablecoins-compared-to-prepaid-funds

 

원화 스테이블코인, 선불충전금과 비교하여 어떤 이점이 있을까? (ASA 오피니언 #8)

원화 스테이블코인, 과연 한국에서 선불충전금과 어떤 차이가 있을까요?

4pillars.io

https://4pillars.io/ko/issues/stablecoin-future-of-money

 

Stablecoin: Future of Money

스테이블코인은 트럼프의 친암호화폐 정책 속에서 잠재적인 미래 기축통화로 부상하고 있습니다. 한국에서 또한 달러 기반 스테이블코인 거래량이 지속적으로 증가하고 있으며, 금융 생태계

4pillars.io

'Own > TIR(Today I Read)' 카테고리의 다른 글

[TIR] 2025.08.22(금)  (0) 2025.08.22
[TIR] 2025.08.19(화)  (0) 2025.08.19
'Own/TIR(Today I Read)' 카테고리의 다른 글
  • [TIR] 2025.08.22(금)
  • [TIR] 2025.08.19(화)
빵빵0
빵빵0
(아직은) 공부하고 정리하는 블로그입니다.
  • 빵빵0
    Hack Your World
    빵빵0
  • 전체
    오늘
    어제
    • 분류 전체보기 (92)
      • Error Handling (7)
      • Project (5)
        • MEV (2)
      • Architecture (0)
        • API (0)
        • Cache (0)
        • 사소한 고민거리 (0)
      • Computer Science (4)
        • Data Structure (2)
        • Database (1)
        • Cloud (0)
        • OS (0)
        • Infra, Network (1)
        • AI (0)
      • Language (8)
        • Go (8)
        • Rust (0)
        • Python (0)
        • Java (0)
      • Algorithm (40)
        • BaekJoon (18)
        • Programmers (7)
        • LeetCode (6)
        • NeetCode (9)
      • SW Books (9)
        • gRPC Up & Running (1)
        • System Design Interview (2)
        • 스프링 입문을 위한 자바 객체지향의 원리와 이해 (6)
        • 블록체인 해설서 (0)
        • 후니의 쉽게 쓴 CISCO 네트워킹 (0)
      • BlockChain (4)
        • Issues (0)
        • Research (4)
        • Tech (0)
      • Own (8)
        • TIR(Today I Read) (3)
        • Personal (2)
        • Novel (0)
        • Memo (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    ethereum
    BaekJoon
    2024
    Programmers
    blockchain
    two pointer
    NeetCode
    candlechart
    DP
    MongoDB
    프로그래머스
    BFS
    chart
    KBW
    EVM
    스택
    백준
    go
    Greedy
    LeetCode
    Hash Table
    블록체인
    BEAKJOON
    golang
    goroutine
    큐
    Palindrome
    Python
    context
    MEV
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
빵빵0
[TIR] 2025.08.21(목)
상단으로

티스토리툴바