Introduction

안녕하세요,
백엔드 개발자
진승우입니다.

"기술을 쌓는 것보다, 병목을 없애고 구조를 설계하는 일에 더 집중합니다."

이벤트 기반 아키텍처와 비동기 처리 구조를 통해
실시간 처리, 데이터 정합성, 업로드 최적화 문제를 해결하고 있습니다.

사진

Projects

파일 변환 서비스

파일 업로드부터 변환 처리, 상태 조회까지를 이벤트 기반 아키텍처로 설계한 서비스입니다.

File Conversion Project Thumbnail
Project Stack

느려지지 않는 변환
흐름을 만드는 기술

사용자는 빠르게 요청하고, 서버는 안정적으로 처리하고, 진행 상태는 즉시 보여주는 구조를 목표로 했습니다.

Event-Driven Architecture CDC / Outbox Redis / SSE RabbitMQ
Detail Section

STAR Detailed View

01

실시간 변환 상황 구현

Redis SSE Pub/Sub
SITUATION상황

초기에는 DB polling 방식(주기적 SELECT)을 고려했으나, 요청이 증가할수록 DB read 부하가 급격히 증가하고 실시간성이 떨어지는 문제가 있었다.

TASK과제
  • 변환 진행 상태를 실시간으로 사용자에게 전달
  • DB 부하를 최소화하면서 낮은 지연으로 상태 동기화
  • Pub/Sub 방식을 구성해 다수 요청 상황에서도 확장 가능한 구조 설계
ACTION실행

DB polling / 서버 메모리 / WebSocket 검토 후 Redis Pub/Sub + SSE 선택

  • Worker - Redis Pub (진행 상태 발행)
  • API - Redis Sub (이벤트 구독)
  • API → SSE로 클라이언트에 push
  • Worker → Redis → API → SSE → Client의 구조 형성
RESULT결과
DB polling 제거
DB read 부하 감소
상태 전달 지연 최소화
실시간 처리 구현

💡 배운 점: "실시간" 문제는 DB보다 메시지 기반 구조로 풀어야 하고, 상태 데이터는 저장보다 전파가 중요하다.

02

Redis + DB 정합성 보정

Redis Database Flush
SITUATION상황

전역 통계를 Redis 기반으로 실시간 제공했지만, 메모리 특성상 장애 발생 시 데이터 유실 가능성이 존재했다.

TASK과제
  • 실시간성과 데이터 안정성 동시에 확보
  • Redis 장애 시 fallback 구조 필요
ACTION실행

Redis → 실시간 통계 저장 → 1분 주기 DB flush → 주기적 재집계

  • Redis에 실시간 통계 저장
  • 1분 주기로 DB flush
  • 재집계로 Redis/DB overwrite
RESULT결과
실시간 + 영속성 확보
장애 시 데이터 복구 가능
hot row 문제 완화
안정적 통계 유지

💡 배운 점: Redis는 빠르지만 영속성은 없고, 실시간 시스템에는 반드시 보정 전략이 필요하다.

03

CDC + Outbox 이벤트 신뢰성

Debezium Outbox RabbitMQ
SITUATION상황

파일 업로드 후 Worker에게 작업을 전달해야 했는데, API에서 DB 저장 + MQ publish를 직접 수행할 경우 이중쓰기 문제가 발생할 수 있었다. 또한 polling 방식은 불필요한 DB 조회가 발생했다.

TASK과제
  • 이벤트 유실 없이 정합성 보장
  • DB polling 없이 변경 기반 이벤트 처리
  • API와 MQ 간 결합도 제거
ACTION실행

API → DB(history + outbox_event) → Debezium → RabbitMQ → Worker

  • Outbox 패턴 + Debezium CDC 선택
  • 동일 트랜잭션에 history + outbox_event 저장
  • Debezium이 outbox_event 변경 감지 후 RabbitMQ publish
  • Worker가 메시지 소비
RESULT결과
이중쓰기 문제 해결
이벤트 유실 가능성 감소
DB polling 제거
서비스 결합도 감소

💡 배운 점: 분산 환경에서는 MQ 발행보다 이벤트 기록이 먼저이고, CDC는 polling을 대체하는 강력한 방식이다.

04

S3 직접 업로드

S3 Presigned URL
SITUATION상황

파일 업로드 시 API 서버를 통해 S3로 업로드하는 구조를 고려했으나, 대용량 파일 처리 시 서버 리소스 사용량 증가 및 병목 가능성이 존재했다.

TASK과제
  • 서버 부하 없이 파일 업로드 처리
  • 업로드 경로 및 파일명은 서버가 통제
  • 확장 가능한 구조 설계
ACTION실행

Client → API(upload-init) → Presigned URL → S3 Upload → API(upload-complete)

  • Presigned URL 기반 클라이언트 직접 업로드 선택
  • API는 Presigned URL 반환
  • Client가 S3 직접 업로드 후 API에 완료 통지
RESULT결과
API 서버 파일 스트림 제거
대용량 업로드 안정화
병목 가능성 감소
확장성 향상

💡 배운 점: 서버는 파일 전달이 아니라 경로와 권한을 관리해야 하고, 대용량 처리에서는 데이터 경로 최적화가 핵심이다.

</> Tech
Spring Boot MySQL Redis RabbitMQ Debezium(CDC) AWS Docker Git