Nginx Reverse Proxy Static TLS

3줄 요약

  • Nginx는 외부 HTTP 요청이 Spring 애플리케이션으로 들어오기 전에 만나는 운영 경계다.
  • 핵심은 reverse proxy, upstream, static cache, TLS termination, timeout, body size, log를 각각 요청 실패와 연결해 읽는 것이다.
  • 백엔드 개발자는 Nginx 설정을 인프라 파일로만 보지 말고, Spring 주소, header, 인증서, 캐시, 로그 증거까지 설명할 수 있어야 한다.

핵심 정리

  • Reverse proxy는 client가 Spring을 직접 호출하지 않게 하고, public port와 내부 upstream을 분리한다.
  • Upstream 장애는 502, 504, 499 같은 Nginx access log 신호로 먼저 드러날 수 있다.
  • 정적 파일은 hash asset과 HTML entry의 cache policy를 분리해야 한다. 모든 파일에 긴 cache header를 붙이면 배포 후 stale asset 장애가 생긴다.
  • TLS termination을 Nginx에서 하면 Spring은 X-Forwarded-Proto, Host, client IP header를 신뢰할 준비가 필요하다.
  • timeout, buffering, client_max_body_size는 사용자 응답 시간뿐 아니라 Spring thread, 업로드 실패, streaming 동작까지 바꾼다.
  • Nginx log는 status, upstream status, request time, upstream response time, request id를 함께 남겨야 장애 중 쓸 수 있다.

헷갈리는 지점

  • 502와 Spring 500을 같은 서버 오류로 묶기 쉽다.
    • 핵심은 502는 Nginx가 upstream과 정상 통신하지 못했다는 신호이고, Spring 500은 upstream이 응답한 애플리케이션 오류라는 점이다.
  • TLS가 Nginx에서 끝나면 Spring은 HTTPS를 모른다고 오해하기 쉽다.
    • 핵심은 forwarded header를 통해 원래 scheme과 host를 전달해야 redirect, cookie secure, absolute URL 판단이 맞는다는 점이다.
  • 캐시를 길게 잡으면 무조건 빠르다고 생각하기 쉽다.
    • 핵심은 fingerprint가 있는 asset만 길게 캐시하고, HTML이나 manifest처럼 배포 진입점은 짧게 관리해야 한다는 점이다.

확인 질문

  • Nginx reverse proxy 장애에서 먼저 볼 로그 신호는 무엇인가?
    • access log의 status, upstream status, request time, upstream response time, error log의 upstream 연결 실패 메시지다.
  • 정적 파일 캐시 정책을 나눠야 하는 이유는 무엇인가?
    • hash asset은 오래 캐시해도 안전하지만 HTML entry가 오래 캐시되면 사용자가 이전 bundle을 계속 받을 수 있기 때문이다.
  • TLS termination 후 Spring 설정에서 확인할 것은 무엇인가?
    • X-Forwarded-Proto, X-Forwarded-For, Host 전달과 Spring의 forwarded header 처리 설정이다.