You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »


Stateful VS Stateless

REST API (Stateless 방식)

✔ 개념

  • REST API는 Stateless(상태 비유지) 방식으로 동작합니다.
  • 클라이언트 요청(Request)은 항상 독립적으로 처리되며, 서버는 클라이언트의 이전 요청 상태를 기억하지 않습니다.
  • 각 요청은 필요한 모든 정보를 포함해야 하며, 서버는 이를 기반으로 응답을 반환합니다.

✔ 장점

확장성(Scalability) 높음

  • 서버는 클라이언트의 상태를 유지하지 않으므로 로드 밸런싱 및 수평 확장이 용이합니다.
  • 여러 서버에서 요청을 처리해도 문제가 없으며, 서버 간 상태 동기화가 필요하지 않습니다.

단순하고 유지보수 용이

  • 상태를 관리할 필요가 없기 때문에 개발이 단순하고 유지보수가 쉬워집니다.
  • API 요청이 독립적이므로 디버깅과 로깅이 용이합니다.

캐싱 활용 가능

  • HTTP 기반이므로 응답을 캐싱하여 성능을 최적화할 수 있습니다.
  • 클라이언트 측에서 캐시를 활용하면 서버 부하를 줄일 수 있습니다.

❌ 단점

실시간성이 부족함

  • 클라이언트가 변경 사항을 지속적으로 확인하려면 주기적인 폴링이 필요하여 비효율적입니다.
  • WebSocket처럼 서버에서 즉시 데이터를 Push할 수 없습니다.

매 요청마다 인증이 필요

  • Stateless 방식이므로 요청마다 인증 정보를 포함해야 하며, 이를 처리하는 과정에서 성능 오버헤드가 발생할 수 있습니다.
  • JWT, OAuth와 같은 인증 토큰을 사용하여 이 문제를 해결할 수 있지만, 여전히 매 요청마다 인증 검증이 필요합니다.

🔹 WebSocket (Stateful 방식)

✔ 개념

  • WebSocket은 Stateful(상태 유지) 방식으로 동작하며, 클라이언트와 서버 간의 지속적인 연결(Persistent Connection)을 유지합니다.
  • 한 번 연결되면, 양방향 통신(Bi-directional Communication)이 가능하며, 서버는 클라이언트의 상태를 기억하고 필요할 때 데이터를 Push할 수 있습니다.

✔ 장점

실시간 데이터 전송 최적화

  • 서버는 클라이언트의 요청 없이도 데이터를 즉시 전송(Push)할 수 있어, 실시간 애플리케이션(예: 채팅, 주식 거래, 게임)에 적합합니다.

네트워크 오버헤드 감소

  • REST API와 달리, 매 요청마다 새로운 연결을 생성하지 않으므로 네트워크 리소스 사용이 효율적입니다.
  • 연결이 유지되므로 인증 과정을 한 번만 수행하면 됩니다.

양방향 통신 가능

  • REST API는 클라이언트 → 서버 방향의 요청-응답 방식이지만, WebSocket은 서버 → 클라이언트도 가능하여 보다 유연한 데이터 흐름을 제공합니다.

❌ 단점

확장성이 낮음

  • 서버가 각 클라이언트와의 연결을 유지해야 하므로 많은 사용자가 접속할 경우 리소스 부담이 증가합니다.
  • 로드 밸런싱이 어렵고, 클러스터링 시 세션 공유 또는 연결 유지 로직이 추가적으로 필요합니다.

복잡한 상태 관리 필요

  • 연결 상태를 유지해야 하므로, 클라이언트가 예기치 않게 연결 해제되거나 재접속할 경우 상태를 관리하는 추가적인 로직이 필요합니다.
  • 예: 세션 유지, 연결 끊김 감지, 재연결 로직 구현.

브라우저 및 네트워크 제한 사항 존재

  • 방화벽, 프록시 등의 네트워크 환경에서 WebSocket 연결이 차단될 수 있습니다.
  • HTTP 기반보다 보안 및 안정성을 고려한 추가적인 설정이 필요할 수 있습니다.

🔹 어떤 방식을 선택해야 할까?

REST API가 적합한 경우

  • 요청과 응답이 독립적인 경우 (예: CRUD API, 데이터 조회 서비스)
  • 서버 확장성과 유지보수가 중요한 경우
  • 네트워크 및 보안 이슈가 신경 쓰이는 경우

WebSocket이 적합한 경우

  • 실시간성이 중요한 경우 (예: 채팅, 스트리밍, 주식 데이터, 게임)
  • 양방향 통신이 필요한 경우 (예: P2P 연결)
  • 연결 유지가 가능하고 성능 최적화가 필요한 경우



Spring WebFlux의 org.springframework.web.reactive.socket 기반의 웹소켓과 전통적인 Spring MVC 기반 웹소켓을 비교해보겠습니다.


1. 아키텍처적 차이

비교 항목Spring WebFlux (org.springframework.web.reactive.socket)Spring MVC (전통적인 웹소켓)
스레드 모델Non-blocking, 이벤트 기반 (Netty, Undertow 등 지원)Blocking, Thread-per-connection (Tomcat, Jetty, Undertow)
리액티브 스트림 지원Flux<Message>, Mono<Message> 기반@MessageMapping 기반
동시성 처리요청 처리에 많은 스레드를 사용하지 않음 (적은 리소스로 높은 성능)많은 동시 접속 시 스레드가 증가, 성능 저하 가능
서버 요구 사항Netty, Undertow, Jetty 등 리액티브 지원 서버 필요Tomcat, Jetty, Undertow 지원
부하 분산가볍고 빠르며 부하를 효과적으로 처리 가능높은 동접자 수 처리 시 성능 저하 가능

2. 성능 및 확장성

비교 항목Spring WebFlux (org.springframework.web.reactive.socket)Spring MVC (전통적인 웹소켓)
성능대량의 동시 요청 처리에 유리동시 연결이 많아지면 성능 저하
부하 분산비동기 이벤트 기반 처리로 효율적스레드 증가로 인한 오버헤드 발생
리소스 관리적은 스레드로 많은 요청 처리 가능많은 동시 요청 시 스레드 리소스 소모 증가
지연 처리이벤트 기반으로 낮은 지연 시간스레드가 많아지면 응답 지연 증가
  • WebFlux 기반 웹소켓비동기 이벤트 기반 모델이기 때문에 최소한의 리소스로 높은 동시성을 처리할 수 있습니다.
  • 반면 Spring MVC 웹소켓Blocking 모델로서 요청당 하나의 스레드를 할당해야 하므로 동접자가 많아질수록 성능 저하가 발생할 수 있습니다.

3. 프로그래밍 모델 차이

Spring WebFlux 웹소켓 (비동기, 리액티브)

@Component
class ReactiveWebSocketHandler : WebSocketHandler {
    override fun handle(session: WebSocketSession): Mono<Void> {
        val input = session.receive()
            .map { it.payloadAsText }
            .doOnNext { println("Received: $it") }

        val output = Flux.interval(Duration.ofSeconds(1))
            .map { "Server response $it" }
            .map(session::textMessage)

        return session.send(output)
    }
}




Spring MVC 웹소켓 (동기, Blocking)

@Controller
class TraditionalWebSocketHandler {

    @MessageMapping("/message")
    @SendTo("/topic/response")
    fun handleMessage(message: String): String {
        println("Received: $message")
        return "Server response: $message"
    }
}

4. 사용 시 고려 사항

WebFlux 웹소켓이 유리한 경우

  • 대규모 동시 연결 처리 (ex. 실시간 채팅, 금융 데이터 스트리밍)
  • 리소스가 제한적인 환경 (ex. 마이크로서비스)
  • Reactive Stack을 기반으로 애플리케이션을 구축할 경우
  • Netty 기반 서버를 사용할 때 최적화된 성능 제공

Spring MVC 웹소켓이 유리한 경우

  • 기존 MVC 프로젝트와의 통합이 필요할 경우
  • 비교적 적은 연결 수를 처리하는 서비스 (ex. 내부 알림 시스템)
  • 기존의 @Controller 기반 프로그래밍이 익숙한 경우
  • 톰캣(Tomcat)을 사용해야 하는 경우 (WebFlux는 기본적으로 Netty를 사용)

5. 정리

비교 항목Spring WebFlux (org.springframework.web.reactive.socket)Spring MVC (전통적인 웹소켓)
비동기 지원✅ 완전한 비동기 리액티브 모델🚫 동기적 처리
성능✅ 높은 동시성 처리 가능🚫 동접자가 많으면 성능 저하
사용하기 쉬운가?🚫 다소 복잡한 코드 구조✅ 전통적인 MVC 패턴과 유사
서버 호환성🚫 Netty, Undertow 등 필요✅ Tomcat, Jetty 지원
적용 사례✅ 실시간 데이터 스트리밍, 채팅, 알림✅ 단순한 웹소켓 기능

🔥 결론

  • 대규모 동시 연결성능이 중요한 서비스에서는 Spring WebFlux비동기 리액티브 웹소켓이 적합합니다.
  • 기존 Spring MVC 기반 프로젝트와의 호환성이 중요하고, 동접자가 많지 않다면 전통적인 Spring MVC 웹소켓이 더 쉬운 선택이 될 수 있습니다.

🚀 즉, 성능과 확장성이 중요한 경우 WebFlux, 익숙한 개발 방식과 기존 시스템 통합이 중요한 경우 MVC 웹소켓을 선택하는 것이 좋습니다.





  • No labels