비동기 통신 방식 비교와 A/B 테스트 설계

2025. 11. 9. 23:49·프로젝트/웹 성능 테스트

1. 비동기 통신의 필요성

우리 프로젝트는 AI 개선안 생성과 원격 보안 점검처럼, 요청 시 즉시 결과가 나오지 않고 백그라운드에서 일정 시간이 소요되는 비동기 작업을 수행합니다.
이런 경우 “언제 끝날지 모르는 작업의 완료 시점”을 클라이언트가 알아차릴 수 있도록 해야 합니다.

즉, 서버에서 처리 중인 상태를 사용자에게 실시간으로 알려주는 통신 방식이 필요합니다.
실서비스에서도 다음 세 가지 패턴 중 하나로 해결합니다.

  1. 폴링(Polling) — 주기적으로 상태 확인 (짧은 폴링 / 롱 폴링)
  2. 실시간 푸시(Streaming) — 서버에서 이벤트를 직접 보냄 (SSE / WebSocket)
  3. 콜백(Webhook) — 서버가 제3의 시스템(대시보드, 외부 서버 등)에 완료 신호를 전송

우리 프로젝트는 이 중 **“사용자 단말(브라우저)에서 AI 결과 완료를 즉시 받는 구조”**가 필요하므로, 웹훅보다는 SSE 또는 롱 폴링 기반 구조가 적합합니다.

 


 

2. 주요 통신 방식 정리

구분 개념 특징  장점 단전
짧은 폴링(Short Polling) 클라이언트가 일정 주기로 /status를 조회 구현이 매우 간단 캐시/프록시 친화, 브라우저 제약 없음 요청 수 많음, 서버/네트워크 낭비
롱 폴링(Long Polling) 서버가 응답을 지연시켜 결과 생길 때 반환 SSE 미지원 환경에서 적합 네트워크 효율↑, 폴링 대비 지연↓ 동시 연결 많을 경우 스레드 점유
SSE(Server-Sent Events) 서버→클라이언트 단방향 실시간 푸시 텍스트 스트림 기반, 자동 재연결 구현 간단, HTTP 친화, 프록시 통과 용이 브라우저→서버 역방향 통신 불가
WebSocket 양방향 연결로 실시간 상호작용 채팅/협업/게임 등에서 활용 완전 양방향, 낮은 지연 운영 복잡도 높음, LB 스티키 필요
웹훅(Webhook) 서버→서버 콜백으로 알림 전송 외부 통합용 비동기 API 통합에 적합 인증/보안 설정 필요

 


 

3. 우리 프로젝트 요구 분석

항목 설명 비고
작업 특성 AI 개선안 생성, 보안 점검 등 → 처리 완료 시점 불명확 비동기성
클라이언트 환경 React 프론트엔드 (브라우저 기반) HTTP 친화적 필요
서버 구조 Spring Boot 백엔드 SSE, 롱폴링 둘 다 구현 용이
요구 기능 결과 생성 완료 시 즉시 알림 실시간 푸시형
양방향 통신 필요 여부 X (요청은 기존 REST, 알림만 단방향) SSE 적합
운영 환경 Nginx Reverse Proxy, HTTPS HTTP 스트림 안정 통과 필요

→ 결론적으로, SSE(Server-Sent Events) 와 롱 폴링(Long Polling) 이 가장 현실적 선택지입니다.

 


 

4. 시나리오 A: SSE

원리

서버에서 클라이언트로 단방향 스트림 연결을 유지하며, 이벤트가 생길 때마다 데이터를 푸시합니다.
HTTP 헤더는 Content-Type: text/event-stream 으로 설정하며, 클라이언트는 EventSource 객체를 통해 구독합니다.

구조

Client (EventSource)
     ↓
Nginx (proxy_buffering off)
     ↓
Spring Boot (SseEmitter)
     ↓
DB (상태 저장)
 

장점

  • 자동 재연결, Last-Event-ID 지원
    브라우저에서 연결이 끊겨도 자동 복구 가능.
  • HTTP 기반이라 LB, Nginx, 프록시 환경에서 안전하게 동작.
  • 구현 난이도 낮음 (SseEmitter 하나로 충분).

단점

  • 단방향(서버→클라이언트) 통신만 가능.
  • 대규모 연결 환경에서는 커넥션 유지 비용 증가.

코드 예시 (Spring Boot)

// Publisher
@Component
public class TestEventPublisher {
  private final SseEmitterManager manager; // testId -> SseEmitter 보관

  public void publishDone(UUID testId, TestDoneEvent payload) {
    manager.send(testId, SseEmitter.event()
        .name("done")
        .id(payload.getSeq())
        .data(payload));
  }
}

// Controller
@GetMapping(value="/sse/tests/{testId}", produces=MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter subscribe(@PathVariable UUID testId, Principal p) {
  SseEmitter emitter = new SseEmitter(0L); // 무제한 또는 LB idle 고려
  manager.register(testId, emitter, p);
  return emitter;
}

 


5. 시나리오 B: 롱 폴링

원리

클라이언트가 /wait 요청을 보내면,
서버는 결과가 준비될 때까지 응답을 일시 지연시킨 후 결과를 반환합니다.
타임아웃(timeout=30s)이 지나면 204(No Content)를 반환하며,
클라이언트는 다시 요청을 보내 재대기합니다.

구조

Client (Axios GET /wait)
     ↓
Spring Boot (DeferredResult)
     ↓
DB 상태 변경 감지 시 complete()
 

장점

  • 모든 브라우저, 모든 프록시 환경에서 안정적으로 작동.
  • SSE 미지원 환경에서도 동작.
  • 커넥션 유지 시간이 짧아 운영 부담 적음.

단점

  • 재요청 오버헤드 존재.
  • 응답 사이에 지연이 발생할 수 있음.

코드 예시

@GetMapping("/api/tests/{id}/wait")
public DeferredResult<ResponseEntity<?>> wait(@PathVariable String id) {
    DeferredResult<ResponseEntity<?>> result = new DeferredResult<>(30000L);
    asyncService.register(id, result);
    return result;
}
 
 

 

6. A/B 테스트 설계

두 방식의 장단점을 실제 환경에서 계측해보기 위해,
SSE 시나리오(A) 와 롱 폴링 시나리오(B) 를 동시에 구성합니다.

테스트 플로우

구분 SSE 롱 폴링
작업 요청 POST /api/tests → testId 동일
진행 이벤트 GET /api/tests/{id}/events GET /api/tests/{id}/wait?timeout=30s
완료 시 동작 서버가 즉시 이벤트 전송 서버가 즉시 응답 반환
끊김 복구 자동 재연결 재요청 필요

측정 지표

지표 설명
Latency(지연) 작업 완료 시점 → 프런트 수신 시점(ms)
Network Cost 요청 수, 데이터 전송량
Server Load CPU 사용률, 커넥션 점유율
Error/Timeout Rate 4xx/5xx, 재연결/재요청 횟수
UX 지표 스피너 유지 시간, 사용자 체감 응답성

시뮬레이션 환경

  • N=100, 1k, 10k 동시 요청 시점별 부하 테스트
  • LB/Nginx idle timeout, 재연결 처리 검증
  • 서버 롤링 배포 중 스트림 끊김 대응 확인

예상 가설

  • SSE는 지연(latency) 면에서 우수하지만,
    동시 커넥션 수가 많을 때 부하 증가 가능.
  • 롱 폴링은 부하 안정성이 높지만,
    요청 횟수 증가로 네트워크 오버헤드 발생 가능.

 


 

7. 결론

  1. 기본 구조는 SSE(Server-Sent Events) 로 운영합니다.
    → Spring + Nginx 환경에 가장 자연스럽고, 완료 이벤트를 즉시 전달 가능.
  2. 대안 및 백업 채널로 롱 폴링(Long Polling) 을 구성합니다.
    → SSE가 불가능한 환경(네트워크 차단, 레거시 브라우저 등)에서 폴백으로 사용.
  3. A/B 테스트를 통해 계량적 데이터 확보 후 결정
    → 실제 트래픽 기반으로 SSE 연결 유지율, 롱 폴링 응답 속도, 서버 커넥션 수를 측정합니다.
    → 이후 인프라 스케일링 전략에 반영합니다.

'프로젝트 > 웹 성능 테스트' 카테고리의 다른 글

장애 대응을 위한 메트릭 모니터링 단 구축(1. Actuator + Micrometer)  (0) 2025.11.28
롱폴링 비동기 완료  (0) 2025.11.27
Nginx 도입 2편: 적용  (0) 2025.11.09
Nginx 도입 1편: 왜 Nginx  (0) 2025.11.06
Server Sent Events(SSE): 구현  (0) 2025.11.02
'프로젝트/웹 성능 테스트' 카테고리의 다른 글
  • 장애 대응을 위한 메트릭 모니터링 단 구축(1. Actuator + Micrometer)
  • 롱폴링 비동기 완료
  • Nginx 도입 2편: 적용
  • Nginx 도입 1편: 왜 Nginx
yoon4360
yoon4360
자바 백엔드 개발자 지망생입니다
  • yoon4360
    yoon4360님의 블로그
    yoon4360
  • 전체
    오늘
    어제
    • 분류 전체보기 (137)
      • 스프링 (17)
      • 프로젝트 (48)
        • 악취 포집기 앱 (4)
        • 기업 일정 관리 웹 (10)
        • 기술 면접 복습 플랫폼 (18)
        • 웹 성능 테스트 (16)
      • CS (9)
      • 자바 (14)
      • 독서 (1)
      • SQL (1)
      • SSAFY (14)
      • 알고리즘 (15)
      • 기술면접 (8)
      • 데이터베이스 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
yoon4360
비동기 통신 방식 비교와 A/B 테스트 설계
상단으로

티스토리툴바