Activities/Focussu 개발일지

[Focussu] 아키텍쳐 설계

oxdjww 2025. 4. 7. 22:04
728x90
반응형

0. 온라인 스터디 플랫폼, Focussu 백엔드 아키텍처 설계기

― 실시간 스트리밍, Kafka, 그리고 Docker Compose까지

캡스톤 프로젝트에서 "실시간 집중도 분석이 가능한 온라인 스터디 플랫폼"을 개발하게 되었다.

단순히 영상 전화를 넘어서, 각 사용자들의 스트리밍 데이터를 AI 서버로 전달하고, 그 분석 결과를 기반으로 각 사람의 집중도를 실시간으로 보여주는 플랫폼이다.

 

이 글은 백엔드 개발자로서 내가 어떤 기술을 선택했고, 왜 그런 선택을 하게 되었는지를 정리한 기록이다.

또, 각종 트러블 슈팅을 시리즈 별로 정리할 예정이다.


1. 핵심 요구사항 정리

  1. 사용자의 비디오/오디오 스트리밍 데이터를 AI 분석 서버로 보내야 한다.
  2. 따라서 WebRTC의 P2P 방식은 사용할 수 없고, 중계 서버(SFU 기반)가 필요하다.
  3. 인증/인가(Spring Security)는 비즈니스 로직과 분리해서 깔끔하게 구성해야 한다.
  4. AI 분석 결과는 Kafka를 통해 비동기적으로 받아야 하며, 백엔드에서 consume 후 DB에 저장해야 한다.

1.1 아키텍쳐(초안)

수행 계획서에 첨부한 초안이며, 실제로는 NoSQL을 쓸지도 고민 중에 있다.

 


2. 기술 스택 선정과 고민의 흔적

2.1 Mediasoup – 스트리밍 중계 서버

처음엔 WebRTC를 활용해서 P2P 구조로 만들까도 생각했다. 하지만 이 구조는 클라이언트끼리 직접 연결되기 때문에, 중간에서 데이터를 가로채서 AI 분석 서버로 전달하는 게 불가능했다.

그래서 서버 기반의 SFU 구조로 방향을 틀었고, 여러 옵션 중에서 mediasoup를 선택했다.

mediasoup는 Node.js 기반 SFU로, 커스터마이징 자유도도 높고 성능도 괜찮다.
가장 좋았던 점은 서버가 모든 클라이언트의 stream을 받아 중계해줄 수 있다는 점이었다.
동시에, 이 stream을 그대로 AI 서버에 포워딩할 수 있어 요구사항과 완벽히 맞아떨어졌다.


2.2 Kafka – 집중도 분석 결과 수신을 위한 메시지 큐

AI 분석 서버는 실시간 스트리밍 데이터를 받아 집중도를 분석한다. 그런데 이 결과를 HTTP로 받아 처리하는 건 너무 비효율적이고, 분석 시간이 일정하지 않아 비동기 구조가 필수적이었다.

그래서 Kafka를 도입했다.

  • AI 분석 서버는 Kafka topic에 집중도 결과를 발행(publish)
  • Spring Boot 백엔드는 Kafka를 구독(consume)하고, 결과를 DB에 저장

Kafka 덕분에 AI 서버와 백엔드가 완전히 decoupling되었다.
처리량이 많아져도 쉽게 스케일링할 수 있고, 분석 지연에도 유연하게 대응 가능하다.


2.3 Spring Boot – 인증과 비즈니스 로직의 허브

Spring Boot는 다음 역할들을 맡는다.

  • JWT 기반 사용자 인증 처리
  • 스터디룸 입장 요청 시, 중계 서버에 요청을 보내 접속 정보 생성
  • 이 정보를 사용자에게 전달해, 스트리밍 서버 연결까지 연결되는 흐름을 만든다.
  • Kafka 구독 후 집중도 데이터를 DB에 저장하는 역할도 수행한다.

TDD로 개발하여, 단위 테스트 별로 안전하게 검증된 API를 만들어보고자 한다.


3. Docker Compose로 인프라 구성

이 모든 걸 안정적으로 구동시키기 위해 Docker Compose를 사용해서 전체 인프라를 컨테이너화했다. 구조는 다음과 같다.

├── docker-compose.yml
├── backend                # Spring Boot 서버
│   ├── Dockerfile
│   └── src, build, ...
├── mediasoup-server       # Node.js 기반 SFU 서버 (별도 디렉토리 존재)
└── kafka
  • backend: JWT 인증, 스터디룸 입장 처리, Kafka consumer, DB 연동 등 비즈니스 로직 담당
  • mediasoup-server: 클라이언트 스트림을 받아 다른 사용자들에게 중계, AI 서버로 스트림 포워딩
  • kafka + zookeeper: 비동기 메시지 브로커

Docker Compose 덕분에 로컬 환경에서도 전체 시스템을 한 줄로 띄울 수 있어서 개발이 수월했고,
이후 배포 시에도 docker swarm이나 k8s로 자연스럽게 확장 가능하다.

꿀팁

필자는 이런 스크립트로 서버 재가동을 자동화하는 습관이 있다.

$ sh rerun.sh
#!/bin/sh

echo "Stopping and removing containers, networks, volumes..."
docker compose down -v

echo "Starting containers in detached mode..."
docker compose up -d

 


4. 실제 흐름 요약

  1. 클라이언트가 Spring Boot 서버로 JWT 기반 인증 + 스터디룸 입장 요청
  2. Spring Boot 서버가 mediasoup 서버에 접속 정보 요청
  3. 생성된 접속 정보를 클라이언트에게 반환
  4. 클라이언트는 mediasoup에 접속하고, 스트림을 업로드
  5. mediasoup는 이 스트림을 다른 사용자들에게 중계, 동시에 AI 분석 서버로 전달
  6. 분석 서버는 집중도 분석 후, Kafka에 메시지 전송
  7. Spring Boot 서버는 Kafka를 구독해서 메시지를 받고, DB에 저장
  8. 사용자 요청 시 집중도 데이터를 API로 반환

5. 마치며:  "설계는 전략이다"

이 프로젝트 초기 아키텍쳐 설계를 하고, 각 요구사항을 반영하는 과정을 통해 "아키텍처는 전략이다"라는 말을 다시 한 번 느꼈다.

기술 하나하나가 서로 잘 맞물려 돌아가도록 설계하고, 문제가 생겨도 쉽게 디버깅하고 확장할 수 있게 만드는 것.
그게 진짜 서버 개발자의 역할이라는 걸 느꼈다.

 

하나의 기술을 선택할 때 많은 고민과 설계를 하는 노력이, 러프한 설계 후 개발하며 하는 고생보다 낫다!

728x90
반응형

'Activities > Focussu 개발일지' 카테고리의 다른 글

[Focussu] Kafka & Redis 통합/단위 테스트  (0) 2025.04.15