cmod.ify
[Cloud] CQRS 실습 본문
728x90
반응형
1. 전체 시스템 흐름
본 프로젝트는 데이터의 저장(Command)과 조회(Query)의 책임을 분리하는 CQRS(Command Query Responsibility Segregation) 패턴을 기반으로 구축됨.
- 입력 단계: 리액트(Frontend)에서 사용자가 도서 정보를 입력하고 등록 요청을 보냄.
- 저장 및 발행 단계: Write 서버(Django, 7000번)가 요청을 받아 MySQL에 원본 데이터를 저장하고, 동시에 Kafka의 cqrstopic이라는 이름의 토픽으로 해당 데이터를 발행(Produce)함.
- 메시지 중계 단계: Kafka 브로커는 전달받은 데이터를 보관하며 컨슈머의 요청을 기다림.
- 동기화 단계: 별도의 컨슈머 프로세스(Consumer)가 카프카를 상시 모니터링하다가 메시지가 들어오면 이를 낚아채서 MongoDB에 저장함.
- 조회 단계: Read 서버(Django, 8000번)는 조회가 필요할 때 MySQL이 아닌 MongoDB를 참조하여 데이터를 반환함.

2. 핵심 파트 설명
- Django Write Server (Port 7000): 데이터 변경(CUD)을 담당. 데이터의 무결성을 위해 관계형 데이터베이스인 MySQL을 사용함.
- MySQL: 시스템의 원본 데이터(Source of Truth)가 저장되는 저장소.
- Kafka & Zookeeper: 분산 메시징 시스템. 서버 간의 결합도를 낮추고 비동기적으로 데이터를 전달하는 중계자 역할을 함.
- Django Read Server (Port 8000): 데이터 조회를 담당. 대량의 비정형 데이터 조회 성능을 위해 NoSQL인 MongoDB를 사용함.
- MongoDB: 조회 전용 데이터 저장소. 카프카를 통해 MySQL의 데이터와 동기화됨.
3. 프로젝트 진행 과정
- 기반 환경 구축: Docker Desktop 설치 및 Docker Compose를 이용한 Kafka, Zookeeper 컨테이너 환경 설정.
- 백엔드 로직 구현: Django 프로젝트 생성 및 REST API 기반의 BookSerializer, View 로직 작성.
- DB 연동 및 마이그레이션: Django와 MySQL 연동 설정 및 테이블 생성.
- 카프카 연동: kafka-python 라이브러리를 이용하여 Write 서버 내 Producer 코드 구현.
- 프론트엔드 연결: React에서 Axios를 사용하여 백엔드 API와 통신하는 기능 구현.
- 동기화 프로세스 구축: 카프카 메시지를 읽어 MongoDB에 저장하는 전용 컨슈머 스크립트 작성 및 실행.
4. 주요 오류 분석 및 해결
- Network Error (CORS 정책 위반)
- 현상: 리액트(3000번)에서 장고(7000번)로 데이터 전송 시 브라우저에서 연결을 차단함.
- 원인: 포트 번호가 다른 두 서비스 사이의 보안 장벽(CORS) 때문임.
- 해결: django-cors-headers 패키지를 설치하고, settings.py의 MIDDLEWARE에 CorsMiddleware 추가 및 CORS_ALLOWED_ORIGINS에 리액트 주소를 등록함.
- ModuleNotFoundError (패키지 미설치)
- 현상: CORS 설정 후 장고 서버 실행 시 corsheaders 모듈을 찾을 수 없다는 에러와 함께 서버 구동 실패.
- 원인: settings.py에 설정은 했으나, 실제 사용 중인 가상환경(myvenv)에 패키지가 설치되지 않음.
- 해결: 터미널에서 pip install django-cors-headers를 실행하여 패키지를 정상 설치함.
- MySQL 접속 권한 오류 (Access Denied 1045)
- 현상: 도커 컨테이너로 MySQL을 실행했으나 장고에서 Access denied for user 'root'@'localhost' 발생.
- 원인: 로컬 PC에 이미 설치되어 실행 중이던 MySQL 서비스가 3306 포트를 선점하여 도커 내부의 MySQL 접속을 방해함.
- 해결: 윈도우 서비스 관리자에서 기존 MySQL 서비스를 중지시켜 3306 포트를 확보한 후 도커 컨테이너를 재시작함.
- Kafka 컨테이너 실행 실패 (CrashLoopBackOff)
- 현상: Docker Compose 실행 시 Kafka 컨테이너가 시작되었다가 즉시 종료됨.
- 원인: 이전 실행 기록인 데이터 볼륨(Volume)의 찌꺼기가 남아 Zookeeper와의 메타데이터 불일치 발생.
- 해결: docker-compose down으로 컨테이너를 내린 뒤 docker volume prune 명령으로 기존 볼륨 데이터를 완전히 삭제하고 재실행함.
- 시리얼라이저 유효성 및 날짜 형식 오류 (400 Bad Request)
- 현상: 통신은 성공했으나 장고 로그에 400 Bad Request가 뜨며 DB 저장 실패. 특히 published_date 관련 에러 발생.
- 원인: 리액트에서 보낸 데이터 키값이 모델 필드와 일치하지 않거나, 필수 항목인 날짜 데이터가 장고가 원하는 YYYY-MM-DD 형식이 아니었음.
- 해결: 리액트의 전송 데이터 객체를 모델 형식에 맞춰 수정하고, new Date().toISOString().split('T')[0]를 사용하여 날짜 형식을 강제로 맞춰 전송함.
- MongoDB 데이터 미동기화
- 현상: 리액트에서 등록 성공 팝업은 뜨지만 MongoDB Compass에서 데이터가 확인되지 않음.
- 원인: Write 서버에서 카프카로 메시지는 발행되었으나, 이를 수신하여 몽고DB에 넣어줄 Consumer 프로세스가 실행되지 않아 흐름이 끊김.
- 해결: 카프카 토픽을 구독하고 몽고DB 클라이언트를 호출하는 별도의 컨슈머 스크립트(read_consumer.py)를 작성하여 상시 실행 상태로 유지함.
728x90
반응형
'클라우드' 카테고리의 다른 글
| [클라우드] 쿠버네티스 #3: 워커 노드 이해 및 배포&scale 실습 (0) | 2026.02.19 |
|---|---|
| [클라우드] 쿠버네티스 #2: 마스터 노드의 4대 아키텍처 및 구축 실습 (0) | 2026.02.19 |
| [클라우드] 쿠버네티스 #1: 핵심 구조 한눈에 보기 (0) | 2026.02.11 |
| [클라우드] MSA 개념 및 용어 정리 (0) | 2026.01.29 |