플러팅 AI/Flask Server

이미지 업로드 방식을 HTTP에서 WebSocket으로 변경한 이유

Solo.dev 2024. 12. 13. 02:27

최근 프로젝트에서 이미지 업로드 방식을 HTTP 요청에서 WebSocket(Socket.IO) 기반으로 변경했습니다. 이번 글에서는 변경한 이유와, 이를 Google Cloud Run과 컨테이너 환경에서 구현한 방법을 공유해 보겠습니다.


1. 기존 HTTP 방식의 한계: 컨테이너 간 동기화 문제

기존에 이미지 업로드는 HTTP 요청 방식으로 처리되었습니다. 그러나 GCP Cloud Run 환경에서 서버를 컨테이너로 배포하면서 몇 가지 문제가 발생했습니다:

  • 컨테이너 간 동기화 문제: GCP Cloud Run은 자동 스케일링을 지원하기 때문에 요청에 따라 여러 컨테이너가 생성됩니다. 이 과정에서 이미지 업로드와 관련된 세션 식별자(sid)가 다른 컨테이너로 전달되거나, 데이터가 일치하지 않는 문제가 발생했습니다.
  • 상태 관리의 복잡성: HTTP는 무상태(stateless) 통신이기 때문에 세션 정보(sid)를 관리하기 위해 별도의 로직이 필요했습니다.

2. WebSocket으로 통합한 이유

이 문제를 해결하기 위해 이미지 업로드와 세션 식별자(sid) 관리를 WebSocket(Socket.IO) 기반으로 통합했습니다. WebSocket은 실시간 양방향 통신을 제공하기 때문에 아래와 같은 이점을 얻을 수 있었습니다:

  • 데이터 동기화 보장: WebSocket은 클라이언트와 서버 간의 지속적인 연결을 유지하므로, 동일한 세션에서 데이터 일관성을 보장합니다.
  • 효율적인 처리: 이미지 업로드 요청과 sid 관리를 한 채널(WebSocket)에서 처리하여 기존 HTTP 방식보다 효율적으로 구현할 수 있었습니다.
  • 실시간 업데이트: 업로드 진행 상태를 실시간으로 제공할 수 있습니다.

3. GCP Cloud Run 환경에서의 구현

우리 프로젝트에서는 Google Cloud Run을 통해 서비스를 배포하고 있습니다. Cloud Run은 다음과 같은 장점을 제공합니다:

  • 자동 스케일링: 요청에 따라 컨테이너를 자동으로 생성/삭제하므로, 트래픽 증가에도 유연하게 대처할 수 있습니다.
  • 무상태 컨테이너 지원: Cloud Run은 무상태(stateless) 컨테이너를 기반으로 동작하기 때문에, WebSocket과 같은 실시간 통신 방식에도 적합합니다.
  • 간편한 배포: 도커 이미지를 빌드한 뒤, 간단한 명령어로 Cloud Run에 배포할 수 있습니다.
    bash
    코드 복사
    gcloud run deploy --image gcr.io/your-project/your-image --platform managed

4. 컨테이너 환경에서 WebSocket과 Cloud Run의 역할

  • 컨테이너란? 컨테이너는 애플리케이션과 모든 종속성을 하나의 패키지로 묶어, 일관된 실행 환경을 제공하는 기술입니다. 컨테이너 환경에서는 애플리케이션이 독립적으로 실행되므로, 서버 간 충돌 없이 확장 가능합니다.
  • Cloud Run에서의 컨테이너 Cloud Run은 컨테이너를 기반으로 동작하며, 아래와 같은 특징을 제공합니다:
    • 컨테이너 이미지를 기반으로 애플리케이션을 실행.
    • 요청 수에 따라 컨테이너를 스케일 아웃하여 리소스 낭비를 최소화.
    • 컨테이너 간에는 별도의 네트워크 통신을 통해 데이터를 주고받음.
  • WebSocket과 컨테이너 WebSocket은 지속적인 연결을 요구하므로, Cloud Run과 같은 무상태(stateless) 환경에서도 적절히 설계해야 합니다. 이를 위해 클라이언트와 컨테이너 간의 연결 상태를 관리하고, 필요한 데이터는 외부 스토리지나 Pub/Sub 같은 GCP 서비스를 통해 공유하는 방식을 적용했습니다.

5. 변경 후의 기대 효과

  • 컨테이너 간 동기화 문제 해결: WebSocket을 사용하여 클라이언트와 컨테이너 간의 실시간 통신을 유지, 데이터 일관성을 확보.
  • 스케일링 안정성 확보: Cloud Run의 자동 스케일링과 WebSocket의 통합으로 트래픽 증가에도 안정적인 성능 유지.
  • 효율적인 데이터 처리: HTTP와 WebSocket 방식을 혼용하던 복잡성을 제거하고, 하나의 통신 방식(WebSocket)으로 단순화.