SeverSent Event의 약자. 클라이언트가 요청 1회만 주면 서버가 지속적으로 응답을 보내는 패턴이다. HTTP프로토콜을 이용한다. 실시간으로 계속 변하는 데이터를 응답해야할때 사용함. 대표적으로 주식 시세 흐름

기존 SpringMVC에서도 SSE를 지원하긴 했다.

// MVC에서도 SseEmitter로 SSE 가능
@GetMapping("/stream")
fun stream(): SseEmitter {
    val emitter = SseEmitter()
    
    // 별도 스레드에서 데이터 전송
    executor.execute {
        repeat(10) {
            emitter.send("데이터 $it")
            Thread.sleep(1000)  // 블로킹
        }
        emitter.complete()
    }
    
    return emitter
}

하지만 현실적으로 MVC에서는 SSE를 사용하면 안된다. MVC + SSE를 사용하면, 사용자 연결 1개당 쓰레드 1개가 고정적으로 점유된다. 연결을 유지하는동안 계속 해당 사용자에게 응답을 보내줘야 하기 때문임. 그말은 동시접속자가 10,000명만 되어도 쓰레드가 무려 10,000개가 필요하다는 의미임.

가상 쓰레드로 이제 해결된거 아닌가?

그래서 자연스러운 패턴은 WebFlux와 SSE를 사용하는 것임. 이들은 태생부터 논블로킹이라 쓰레드를 무지막지하게 잡고 있지 않는다. 소수의 이벤트 루프 쓰레드만 있으면 됨.

// WebFlux - 논블로킹이라 스레드 점유 없음
fun stream(request: ServerRequest): Mono<ServerResponse> {
    return ServerResponse.ok()
        .contentType(MediaType.TEXT_EVENT_STREAM)
        .body(
            Flux.interval(Duration.ofSeconds(1)),
            Long::class.java
        )
}