SSE 연결 유지 시간과 Ping 메시지 활용

eunoia73·2025년 2월 20일
1

TIL

목록 보기
16/32

1. 문제 상황

AI를 활용한 사내 캘린더 프로젝트에서 SSE를 이용해 일정 생성 및 알림 생성 시 실시간 알림 기능을 구현하게 되었다.
이 과정에서 SSE 연결 유지 시간을 어느 정도로 설정하는 것이 적절할지에 대한 고민이 생겼다.

❗️ 짧은 연결 시간의 문제점:
클라이언트가 빈번하게 재연결 요청을 보내 네트워크 오버헤드가 증가
네트워크가 불안정한 환경(ex. 모바일)에서 연결 안정성이 저하될 가능성

❗️ 긴 연결 시간의 문제점:
사용하지 않는 연결도 리소스를 점유하여 서버 부하 증가
연결이 끊어진 클라이언트를 감지하는 데 시간이 오래 걸릴 수 있음

SSE(Server-Sent Events)란?

서버에서 클라이언트로 데이터를 실시간으로 전송할 수 있는 단방향 통신 방식

단방향 실시간 통신: 서버 → 클라이언트로만 데이터 전송.
HTTP 기반: 클라이언트는 EventSource 객체를 사용해 간단히 설정 가능.
자동 재연결: 네트워크 문제가 발생해도 자동으로 복구 시도.

2. 적절한 SSE 연결 유지 시간

일반적으로 SSE 연결 유지 시간은 5분 ~ 30분으로 잡고, Ping 메시지를 주기적으로 보내 연결 상태를 확인한다.

SseEmitter emitter = new SseEmitter(30 * 60 * 1000L); // 30분 유지

3. Ping 메시지를 활용한 안정성 관리

Ping 메시지란?

서버와 클라이언트 간의 연결 상태를 확인하고, 비활성 연결을 감지하거나 네트워크 문제를 조기에 발견하기 위해 주기적으로 전송되는 작은 데이터 패킷

  • 클라이언트의 활성 상태를 확인하여 비활성 연결을 정리
  • 네트워크 문제를 조기에 감지하고 자동 복구 가능

Ping 메시지의 전송 주기

  • 일반적으로 30~60초 간격으로 전송.
  • Ping 메시지는 크기가 작아 오버헤드가 적음(수십 바이트 수준)

Ping 메시지의 효과

  • 비활성 클라이언트를 감지하여 불필요한 리소스 점유 방지
  • 네트워크 문제를 빠르게 파악하고 안정성을 높임
  • SSE 연결의 효율적 관리 및 서버 부하 감소
 	/**
     * 모든 클라이언트에게 Ping 메시지 전송
     */
    private void sendBroadcastPing() {
        emitters.forEach((userId, emitter) -> {
            try {
                emitter.send(SseEmitter.event().name("ping").data("keep-alive"));
            } catch (IOException | IllegalStateException e) {
                log.warn("Ping 메시지 전송 실패 - 사용자: {}, 이유: {}", userId, e.getMessage());
                emitters.remove(userId);
            }
        });
    }

    /**
     * 1분마다 자동으로 Ping 메시지 전송
     */
    @Scheduled(fixedRate = 60 * 1000L)  // 1분마다 ping 전송
    public void scheduledPing() {
        sendBroadcastPing();
    }

4. Ping 메시지의 브로드캐스트 방식

여러 클라이언트에게 동시에 동일한 메시지를 전송하는 방식

  1. 서버 부하 감소 - 동일한 Ping 메시지를 한 번 생성한 뒤, 여러 클라이언트에게 동시에 전송하므로 서버의 처리 부하가 줄어든다
  2. 네트워크 효율성 향상 - 한 번의 데이터 패킷으로 여러 클라이언트에게 메시지를 전달하므로 네트워크 트래픽을 줄일 수 있다. (각 클라이언트에게 메시지를 개별적으로 전송하면 네트워크 트래픽이 증가한다)
  3. 코드 단순화 - 동일한 데이터를 여러 클라이언트에 전송하기 때문에 코드가 간단해지고 유지보수가 용이하다
  4. 대규모 사용자 환경에서 유리 - 서버 리소스를 효율적으로 사용

✅ 결론

  • SSE 연결 유지 시간은 5~30분이 일반적이며, 클라이언트의 빈번한 재연결을 방지하는 것이 목표이다
  • Ping 메시지는 30~60초마다 보내는 것이 적절하며, 부하를 고려하여 주기를 조절해야 한다
  • 브로드캐스트 방식으로 Ping을 보내면 서버 부하를 줄일 수 있다

🗂️ 레퍼런스
https://developer.mozilla.org/ko/docs/Web/API/Server-sent_events
https://velog.io/@baekgom/SSE-Server-Sent-Event-%EC%95%8C%EB%A6%BC-%EA%B8%B0%EB%8A%A5
https://inma.tistory.com/179

0개의 댓글