whdudev

[auctify] Nginx 리버스 프록시일 경우 SSE연결 오류 해결 본문

PROJECT

[auctify] Nginx 리버스 프록시일 경우 SSE연결 오류 해결

whdudev 2025. 4. 30. 18:44

✅ 문제 상황

로컬 환경에서는 SSE(Server-Sent Events) 연결이 정상적으로 작동했지만,
서버 환경에서는 SSE 연결이 수립되지 않거나 응답이 도착하지 않는 문제가 발생했습니다.

 

 

✅ 문제 해결 과정

처음에는 코드에는 문제가 없어 보였기 때문에, 로컬과 서버 환경의 차이점을 중점적으로 분석했습니다.
그 결과, 서버에서는 Nginx가 리버스 프록시로 동작하고 있다는 점이 문제의 핵심이었습니다.

Nginx는 기본적으로 응답을 버퍼링하거나, 일정 시간 응답이 없으면 연결을 끊는 설정이 적용되어 있습니다.
이로 인해, 실시간으로 데이터를 스트리밍해야 하는 SSE 연결이 정상적으로 유지되지 않았던 것입니다.

 

 

✅ 해결 방법

Nginx 설정에서 /api/sse/subscribe 경로에 대해 아래와 같이 SSE에 필요한 설정을 명시했습니다:

 

# ✅ 알림용 SSE 구독 endpoint 설정
location /api/sse/subscribe/notification {
    # 백엔드 Spring Boot 서버로 프록시 요청 전달
    proxy_pass http://localhost:8080;

    # 클라이언트의 원래 Host 헤더를 전달
    proxy_set_header Host              $host;
    # 클라이언트의 실제 IP 주소를 전달
    proxy_set_header X-Real-IP         $remote_addr;
    # 프록시 체인을 따라 클라이언트 IP를 계속 유지
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    # 원래 요청의 프로토콜 (http/https) 전달
    proxy_set_header X-Forwarded-Proto $scheme;

    # SSE는 스트리밍 기반이라 버퍼링을 비활성화해야 즉시 전송됨
    proxy_buffering off;

    # 캐시를 비활성화하여 실시간 데이터 흐름 유지
    proxy_cache off;

    # HTTP 1.1은 SSE 스트리밍에 필요한 지속 연결(persistent connection)을 지원
    proxy_http_version 1.1;

    # Transfer-Encoding: chunked 전송을 비활성화 (일부 서버에서 문제 생기는 경우 대비)
    chunked_transfer_encoding off;

    # 연결 타임아웃을 1시간(3600초)으로 설정 (연결 유지 목적)
    proxy_read_timeout 3600;

    # 클라이언트가 캐시하지 않도록 응답 헤더 설정
    add_header Cache-Control no-cache;

    # SSE는 반드시 이 Content-Type으로 전송돼야 브라우저에서 인식됨
    add_header Content-Type text/event-stream;
}

# ✅ 입찰용 SSE 구독 endpoint 설정
location /api/sse/subscribe/bid {
    # 동일한 설정을 사용하며, 입찰 기능용 SSE 스트림에 사용
    proxy_pass http://localhost:8080;

    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    proxy_buffering off;
    proxy_cache off;
    proxy_http_version 1.1;
    chunked_transfer_encoding off;
    proxy_read_timeout 3600;

    add_header Cache-Control no-cache;
    add_header Content-Type text/event-stream;
}

이 설정을 통해 Nginx가:

  • SSE 연결을 버퍼링하지 않고,
  • 응답을 캐싱하지 않으며,
  • 연결을 장시간 유지하고,
  • 클라이언트가 SSE 스트림으로 인식할 수 있도록 적절한 헤더를 전달하도록 구성했습니다.

 

✅ 결과

설정 적용 후, 서버 환경에서도 SSE 연결이 정상적으로 수립되고 실시간 이벤트가 전달되는 것을 확인했습니다.
Nginx가 중간에 있을 경우, SSE나 WebSocket과 같은 지속 연결이 필요한 기능은 별도 설정이 반드시 필요하다는 점을 다시금 확인하게 된 사례였습니다.