문제 발생
서버 log에는 1초마다 SSE event를 기록하지만 브라우저에는 여러 event가 한꺼번에 나타납니다. application flush만 확인하고 끝내면 reverse proxy나 압축 계층에서 응답을 모으는 상황을 놓칠 수 있습니다.
SSE는 proxy buffering과 압축 때문에 event가 모여서 도착할 수 있어 streaming route에서 buffering 정책을 분리해야 합니다.
원인 분석
Nginx의 proxy_buffering 기본값은 on입니다. 켜져 있으면 upstream 응답을 buffer에 저장하고 필요하면 임시 파일도 사용할 수 있습니다. upstream이 작은 chunk를 보냈다는 사실과 client가 즉시 받았다는 사실은 다릅니다. curl -N으로 proxy 전후 endpoint를 각각 호출하고 event 시각, response header와 실제 도착 시각을 비교합니다. CDN이나 다른 proxy가 앞에 있다면 그 계층도 따로 봅니다.
해결 방안
일반 API 전체가 아니라 SSE location에서만 buffering을 끕니다.
location /api/events {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 1h;
}
application이 X-Accel-Buffering: no를 보내 경로별로 제어할 수도 있지만 proxy_ignore_headers 설정에 따라 무시될 수 있습니다. 수정 뒤 event 간격, 연결 종료, 재연결과 동시 연결 수를 확인하고 장기 timeout이 worker connection 예산에 미치는 영향도 봅니다.
공식 문서
실제 nginx -T 결과와 앞단 CDN·load balancer의 buffering 설정까지 확인합니다.