[TIR] 2025.08.19(화)

2025. 8. 19. 17:08·Own/TIR(Today I Read)

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

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

 

✏️ gin vs fiber 프레임워크 성능 비교 고민

fiber는 fasthttp 기반

fasthttp는 Go 표준 net/http 패키지를 대체하는 고성능 HTTP 구현체, 최대 10배 빠른 성능 제공
net/http는 고루틴 기반으로 매 요청마다 새로운 고루틴을 생성하는 "fire and forget" 모델
fasthttp는 worker pool을 사용해 미리 초기화된 워커풀이 요청을 처리하는 "zero allocation" 모델
또한, fasthttp는 HTTP/1.1 파이프라이닝을 완전 지원
But, net/http 만큼 완전히 개발안돼서 HTTP/2 같은 최신 기능 제한적
서버가 초당 수천 개의 소~중간 크기 요청을 처리해야 하고 일관된 낮은 밀리초 응답 시간이 필요한 고성능 엣지 케이스일 때 유리

 

fiber의 zero allocation 전략

- worker pool 모델: 미리 초기화된 워커들이 요청 처리

- 객체 재사용: Request/Response 객체를 재사용하여 GC 부담 감소

- 최소 할당: 핫 패스에서 메모리 할당 최소화

- 효율적인 헤더 처리: net/http는 map[string][]string으로 파싱하고 []byte에서 string으로 변환하지만, fasthttp는 []byte를 직접 처리

 

1. Gin

  • 장점
    • 성숙한 생태계와 풍부한 미들웨어
    • 학습 곡선이 완만
    • 대규모 커뮤니티 지원
    • net/http 기반으로 표준 호환성 우수
  • 단점
    • Fiber 대비 약간 낮은 성능
    • 동기식 처리 중심 - 비동기 지원 부족, 대규모 동시 요청 처리에 제약
    • 복잡한 기능에서는 학습 곡선이 가파름
  • 사용 케이스
    • 전통적인 REST API
    • 엔터프라이즈 앱
    • 안전성이 최우선인 프로젝트
    • 팀이 Go 표준에 익숙한 경우

2. Fiber

  • 장점
    • fasthttp 기반으로 zero memory aoolcation과 뛰어난 성능
    • 대용량 동시 연결 효율적 처리
    • Express.js 스타일로 Node.js 개발자에게 친숙
  • 단점
    • fasthttp 제약사항 - HTTP/2 지원 제한
    • 상대적으로 작은 생태계
    • net/http와 완전 호환 안됨
  • 사용 케이스
    • 고성능 MSA
    • 실시간 앱
    • 최대 처리량이 중요한 API
    • Node.js 배경의 개발팀

 

✏️ http response compression 기법 or streaming 성능 비교 고민

1. Compression 분석

  • 장점
    • 대역폭 절약
    • 전송 시간 단축
    • 비용 절감(네트워크 대역폭, 스토리지 비용 등)
  • 단점
    • CPU 오버헤드 (실시간 압축 시 서버 부하 증가)
    • 지연 시간 증가 (압축/해제 시간 만큼 지연 증가, 작은 파일에서는 오히려 성능 저하 가능성)
    • 복잡성 증가 (압축 알고리즘 선택의 복잡성, 클라이언트 지원 여부 확인 필요)
  • 메모
    • 최소 크기 임계값 설정해서, 그 사이즈 이상만 압축

2. Streaming 분석

  • 장점
    • 메모리 효율성 (대용량 데이터셋을 메모리에 모두 로드하지 않고 점진적으로 발송, 서버 메모리 사용량 절약 가능)
    • 실시간 응답성 (chunk 단위)
    • 백프레셔 처리 (네트워크가 느린 클라이언트에게 자동으로 속도 조절, 서버 리소스 보호)
  • 단점
    • 복잡한 에러 처리 (스트리밍 시작 후 HTTP 상태 코드 변경 불가, 중간에 오류 발생시 복구 어려움)
    • 캐싱 제한 (대부분의 HTTP 캐시가 완전한 응답만 캐싱, CDN 효율성 저하)
    • 클라이언트 복잡성 (클라이언트에서 청크별 처리 로직 필요, 버퍼링 및 백프레셔 관리)

 

✏️ go에서 동시성 제어를 위한 패턴

semaphore pattern vs 전역 worker pool

 

1. 세마포어 (Semaphore) 패턴

  • 개념: 동시에 실행할 수 있는 고루틴의 개수만 간단하게 제어하는 방식입니다. 놀이공원에 입장객 수를 제한하는 것과 같습니다. 정해진 수만큼만 안으로 들어갈 수 있고, 한 명이 나오면 다음 한 명이 들어갑니다.
  • 구현: chan struct{}를 버퍼 크기를 주어 만들면 아주 쉽게 구현할 수 있습니다.
  • 동작 방식:
    1. for 루프를 돌면서 작업을 시작하기 전에 세마포어 채널에 데이터를 보냅니다 (sem <- struct{}).
    2. 채널 버퍼가 가득 차면, 다른 고루틴이 작업을 끝내고 채널에서 데이터를 뺄 때(<-sem)까지 for 루프는 대기합니다.
    3. 각 고루틴은 시작하자마자 defer를 이용해 작업이 끝나면 채널에서 데이터를 빼도록 등록합니다.
  • 장점
    • 단순함: 기존 코드 구조를 거의 바꾸지 않고 몇 줄만 추가해서 적용할 수 있습니다. for 루프를 그대로 사용하면서 동시성만 제어하고 싶을 때 완벽합니다.
    • 가벼움: 별도의 작업 큐나 워커 고루틴을 관리할 필요가 없어 오버헤드가 적습니다.
    • 유연성: 필요할 때마다 고루틴을 생성하므로, 작업이 없을 때는 아무런 리소스도 차지하지 않습니다.
  • 단점
    • 리소스 비효율성: 각 고루틴이 필요할 때마다 생성되고 소멸됩니다. 또한 각 고루틴이 DB 커넥션 같은 공유 리소스를 개별적으로 획득하고 반납해야 해서 리소스 풀링에 비효율적일 수 있습니다.
    • 제어의 한계: 단순히 실행 개수만 제어할 뿐, 작업의 취소, 우선순위 지정, 결과 수집 등 복잡한 제어가 어렵습니다.

2. 워커 풀 (Worker Pool) 패턴

  • 개념: 정해진 수의 워커 고루틴을 미리 만들어두고, 이 워커들이 작업 큐(보통 채널)에서 작업을 하나씩 가져와 처리하는 방식입니다. 공장에 정해진 수의 작업자가 있고, 컨베이어 벨트에 놓인 일감을 가져가 처리하는 모습과 같습니다.
  • 구현: 작업을 담을 채널(jobs)과 결과를 담을 채널(results), 그리고 정해진 수의 워커 고루틴을 실행하는 코드가 필요합니다.
  • 동작 방식:
    • 정해진 수(workerCount)의 워커 고루틴들을 미리 실행시켜 둡니다. 이 워커들은 모두 jobs 채널을 바라보며 대기합니다.
    • for 루프에서는 고루틴을 직접 실행하는 대신, 처리할 작업을 jobs 채널에 보내기만 합니다.
    • 워커 중 하나가 jobs 채널에서 작업을 가져가 처리합니다. 처리가 끝나면 다시 jobs 채널을 바라보며 다음 작업을 기다립니다.
  • 장점
    • 리소스 효율성: 워커 고루틴들이 계속 재사용되므로 고루틴 생성/소멸 비용이 없습니다. 각 워커가 DB 커넥션 풀에서 커넥션을 하나씩 할당받아 사용하면 전체 시스템의 커넥션 수를 예측하고 제어하기 매우 용이합니다.
    • 강력한 제어: 작업 큐의 크기를 조절해 백프레셔(Back-pressure)를 구현하거나, 워커들을 한 번에 종료시키는 등(Graceful Shutdown) 정교한 제어가 가능합니다.
    • 안정성: 시스템이 받을 수 있는 부하의 최대치를 명확하게 제한하여 갑작스러운 트래픽 증가에도 안정적으로 동작합니다.
  • 단점
    • 복잡성: 세마포어 패턴보다 초기 구현이 복잡합니다. 작업 큐, 결과 큐, 워커 로직 등 신경 쓸 부분이 더 많습니다.
    • 지속적인 리소스 사용: 작업이 없어도 워커 고루틴들은 계속 메모리에 상주하며 대기 상태를 유지합니다.

✏️ worker pool 의 큐 종류

  1. 여러 개의 명명된 큐 (Named Queues / Multi-Queue System)
    • 작업의 종류나 중요도에 따라 여러 개의 큐를 만듭니다. (예: high_priority_queue, nft_update_queue, default_queue)
    • 워커들은 특정 큐(들)만 구독하도록 설정할 수 있습니다. 예를 들어, 전체 16개의 워커 중 4개는 항상 high_priority_queue만 처리하고, 나머지 12개는 nft_update_queue와 default_queue를 처리하도록 할당합니다.
    • 이렇게 하면 nft_update_queue가 아무리 꽉 차 있어도, high_priority_queue의 작업은 전용 워커에 의해 즉시 처리될 수 있습니다. "각 작업별로 최소 실행 리소스(워커 수)를 보장하고, 전체 워커 수를 관리"하는 아이디어.
  2. 작업 우선순위 큐 (Priority Queue): 단일 큐를 사용하지만, 큐 자체가 우선순위를 인지하는 방식입니다.
    • 큐에 작업을 넣을 때 우선순위(예: 1~10)를 함께 지정합니다.
    • 워커는 큐에서 작업을 꺼낼 때, 들어온 순서가 아니라 우선순위가 가장 높은 작업을 먼저 가져갑니다.
    • 구현은 container/heap 패키지를 이용하면 상대적으로 쉽게 할 수 있습니다.
  3. 가중치 기반 공정 큐 (Weighted Fair Queuing): 여러 큐에서 작업을 꺼내가는 비율을 조절하는 방식입니다.
    • 중앙에 '디스패처'가 있고, 여러 개의 작업 큐가 있습니다.
    • 디스패처는 "high 큐에서 3개, default 큐에서 1개"와 같은 정해진 비율로 작업을 꺼내 워커들에게 분배합니다.
    • 이를 통해 어떤 큐도 완전히 무시되지 않도록 보장합니다.

 

✏️ HTTP/1.1 vs HTTP/2

학교에서 배운 것 같은데... 가물가물해서 서치해봤다.

fiber가 아무리 성능이 좋다해도 http/2 기능들이 온전히 지원되지 않는다면 꽤나 단점으로 작용할 것 같은데, fiber을 쓰게 된다면 정확히 어떤 부분에서 http/2가 호환이 안되는지 확인해보고, 서비스 지원에 문제가 없는지 검토를 해야할 것 같다.

(추후 블로그 글로 자세히 적어보는걸로!)

https://dev-ws.tistory.com/124

 

HTTP/1.1와 비교하면서 알아보는 HTTP/2

HTTP/1.1과 HTTP/2HTTP/2는 HTTP/1.1과 어떤 점이 다른지 알아보기에 앞서, 왜 HTTP/2가 등장하게 되었는지를 먼저 이해하도록 하자. HTTP의 유래는 하이퍼텍스트 전송으로, 실은 논문을 전송하기 위해 만들

dev-ws.tistory.com

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

[TIR] 2025.08.22(금)  (0) 2025.08.22
[TIR] 2025.08.21(목)  (1) 2025.08.21
'Own/TIR(Today I Read)' 카테고리의 다른 글
  • [TIR] 2025.08.22(금)
  • [TIR] 2025.08.21(목)
빵빵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)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

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

티스토리툴바