Files
2026-09-15 01:37:26 +09:00

4.5 KiB

Go Multi-functional Reverse Proxy

Nginx, HAProxy, Envoy 등의 최신 리버스 프록시 솔루션들에서 영감을 받아 순수 Go 언어로 개발된 고성능 다기능 리버스 프록시 및 로드 밸런서입니다. TCP, UDP, HTTP, HTTPS 트래픽을 모두 제어하고 라우팅할 수 있으며, 클라우드 네이티브 환경에 적합한 무중단 설정 리로드 및 헬스 체크 기능을 내장하고 있습니다.

주요 기능 (Features)

  • L7 HTTP / HTTPS 프록시
    • 도메인(Host) 및 URL 경로(Path) 기반의 세밀한 라우팅
    • 여러 백엔드 서버 간의 Round-Robin 로드 밸런싱
    • TLS(HTTPS) 터미네이션 동시 지원 (인증서 설정 가능)
  • L4 TCP / UDP 프록시
    • 데이터베이스, Redis, 게임 서버 등 TCP 기반 트래픽 포워딩 지원
    • 자체 NAT 세션 관리 테이블을 이용한 UDP 트래픽 포워딩 (DNS 등)
  • 고가용성 및 안정성
    • Active Health Check: 백그라운드에서 주기적으로 서버 상태를 점검하고, 죽은 서버는 라우팅 풀에서 제외 (Circuit Breaker)
    • Hot-Reloading (fsnotify): 서버 재시작 없이 설정 파일(config.yaml)을 저장하는 즉시 라우팅 룰 갱신
    • Graceful Shutdown: 프로세스 종료 시그널(Ctrl+C) 수신 시, 처리 중인 클라이언트의 요청이 끝날 때까지 대기 후 안전하게 서버 종료
  • 확장 가능한 미들웨어 체인
    • IP 기반의 Rate Limiting (Token Bucket 알고리즘) 적용을 통한 트래픽 과부하 방어
    • 패닉(Panic) 복구 및 구조화된 접근 로깅(Access Logging) 내장

🛠 빌드 및 실행 방법

1. 요구 사항

  • Go 1.20 이상 버전 설치 권장

2. 빌드

# 프로젝트 디렉토리로 이동
cd go-proxy

# 의존성 패키지 다운로드 및 빌드
go mod tidy
go build -o proxy.exe ./cmd/proxy

3. 실행

서버를 실행할 때 -config 플래그로 설정 파일 경로를 지정할 수 있습니다. (기본값: config.yaml)

./proxy.exe -config config.yaml

⚙️ 설정 파일 가이드 (config.yaml)

설정은 YAML 포맷으로 작성되며 http, tcp, udp 블록을 각각 독립적으로 활성화할 수 있습니다. 설정 파일을 수정하고 저장하면 프록시 서버가 재시작 없이 즉시 변경 사항(HTTP 라우팅 룰 등)을 반영합니다.

http:
  port: 8080
  tls:
    enabled: false       # true로 변경 시 HTTPS 서버 활성화
    port: 443
    cert_file: "./cert.pem"
    key_file: "./key.pem"
  
  routers:
    # 1. 다중 백엔드 로드 밸런싱 (경로 기반)
    - path: "/api/v1"
      backends:
        - "http://localhost:8081"
        - "http://localhost:8082"
      strip_prefix: true  # 백엔드로 전달 시 /api/v1 접두사 제거

    # 2. 도메인 기반 라우팅
    - host: "admin.local"
      path: "/"
      backend_url: "http://localhost:8083" # 단일 백엔드도 지원
      strip_prefix: false

    # 3. 기본 폴백 라우터 (Catch-all)
    - path: "/"
      backends:
        - "http://localhost:9000"

# TCP 스트림 프록시 설정 (DB, 캐시 서버 등)
tcp:
  port: 9000
  backend: "localhost:3306" # MySQL 트래픽 포워딩 예시

# UDP 스트림 프록시 설정 (DNS, 게임 등)
udp:
  port: 5353
  backend: "8.8.8.8:53" # Google DNS로 트래픽 포워딩 예시

🏗 시스템 아키텍처 개요

  1. cmd/proxy/main.go: 어플리케이션 진입점. 설정을 로드하고, 미들웨어를 구성하며, TCP/UDP/HTTP/HTTPS 각 서버의 인스턴스를 Goroutine으로 띄우고 시스템 시그널을 대기(Graceful Shutdown)합니다.
  2. internal/config/watcher.go: fsnotify를 사용해 설정 파일을 감시하고, 변경 시 라우터에 Thread-safe하게 룰을 주입합니다.
  3. internal/router/router.go: HTTP 요청이 들어올 때 URL Path, Host를 파싱하여 적절한 캐싱된 ReverseProxy 엔진으로 넘깁니다.
  4. internal/proxy/http.go: httputil.ReverseProxy 기반. 백그라운드에서 백엔드 서버의 상태를 핑(TCP Dial)하여 체크(Health Check)하고, 라운드 로빈(Round-Robin)으로 분산합니다.
  5. internal/proxy/udp.go: UDP 특성상 커넥션이 없으므로 자체적인 NAT 세션 테이블(Client Address 매핑)을 만들어 스트림을 라우팅하고, Inactive 세션을 GC(Garbage Collection) 합니다.
  6. pkg/middleware: 로깅, 복구(Recovery), Rate Limiting(IP 기준 트래픽 방어) 로직 체인.