Skip to content

SSE 응답이 계속 대기 중(Pending)으로 유지되는 문제

kbyunghoon edited this page Feb 19, 2025 · 1 revision

프로젝트에서 알림 기능 구현을 위해 SSE(Server-Sent Events)를 사용했다. SSE 기능을 구현하던 중 문제가 발생하였다.

1. 로컬 알림테스트

클라이언트는 /subscribe 엔드포인트를 통해 SSE를 구독하고, 서버는 JSON 형식의 메시지를 전송한다. (클라이언트에서는 JSON.parse()를 사용하여 문자열을 JSON 객체로 변환하였다.)

public void sendAll(SendAlarm sendAlarm) {  
  sseEmitters.forEach((userId, emitter) -> {  
	  try {  
		  emitter.send(  
			  SseEmitter.event()  
				 .name(String.valueOf(sendAlarm.getStatus()))  
				 .data(sendAlarm)  
			  );  
		  } catch (IOException e) {  
			  sseEmitters.remove(userId);  
	  }  
  });  
}

enter image description here

로컬에서는 구독 후 정상적으로 SSE 알림이 전송되는 것을 확인했다.

2. 문제 발생

로컬에서는 정상적으로 작동하는 것을 확인하고 개발 서버에 배포를 하였고 이후 문제가 발생하기 시작했다.

enter image description here

개발 서버에 배포 후, 클라이언트에서는 /subscribe 엔드포인트에 접속했음에도 불구하고 응답이 계속 대기 중(Pending) 상태로 유지되는 현상이 발생했다.

  • 서버 로그: 구독은 정상적으로 이뤄지고, 메시지도 전송되고 있음이 확인됨
  • 클라이언트 코드: 문제 없음
  • 특이사항: 서버를 재배포(서버 종료 후 재시작)하면, 대기 중이던 메시지가 한 번에 응답으로 도착함

원인 분석: Nginx 프록시 버퍼링

문제의 원인은 Nginx 프록시 버퍼링에 있었다.

  • 프록시 버퍼링 동작: 기본적으로 Nginx는 서버에서 받은 응답을 내부 버퍼에 저장한 후, 버퍼가 채워질 때까지 클라이언트로 전송하지 않는다.
  • 문제점: 이로 인해 SSE 메시지가 즉시 전달되지 않고, 버퍼링된 상태로 대기하게 된다.

3. 해결

두 가지 방법으로 문제를 해결할 수 있다.

Nginx 설정에서 프록시 버퍼링 비활성화

Nginx 설정 파일에서 다음과 같이 프록시 버퍼링을 비활성화한다.

proxy_buffering off;

응답 헤더로 버퍼링 동작 제어

서버 응답 시 헤더에 X-Accel-Buffering 값을 no로 설정하여 Nginx가 버퍼링하지 않도록 지정할 수 있다.

response.setHeader("X-Accel-Buffering", "no");

이렇게 설정하면, Nginx가 SSE 메시지를 버퍼링하지 않고 클라이언트에 즉시 전송할 수 있다. 이렇게 응답 시 헤더에 지정하여 해당 문제를 해결하였다.