마이크로서비스 아키텍처 · 모놀리스에서 MSA 로 · 실습
모놀리스를 두 서비스로 분리하기
목표
주문과 재고가 한 프로세스에 들어 있는 모놀리스를, 계약을 먼저 고정한 뒤 두 개의 독립 서비스로 분리하고, 분리 전후의 응답이 같은지 자동으로 검증한다.
왜 중요한가
서비스 분리에서 실제로 어려운 부분은 코드를 옮기는 일이 아닙니다. 옮기고 나서도 같은 답이 나오는지 확인하는 일, 그리고 데이터 소유권까지 함께 옮겼는지 확인하는 일입니다. 현장에서 가장 흔한 실패는 "서비스는 나눴는데 테이블은 공유"입니다. 이러면 배포는 독립됐지만 스키마 변경은 여전히 두 팀의 합의를 필요로 합니다. 결합은 코드가 아니라 데이터에 있었기 때문입니다. 그래서 이 실습은 코드를 옮기기 전에 계약(contract)을 파일로 먼저 고정하고, 마지막에 소스를 검사해 데이터 접근이 정말로 끊겼는지 확인합니다. 교살 무화과 방식에서 파사드 뒤의 두 구현이 같은 답을 준다는 확신이 없으면 트래픽을 넘길 수 없습니다.
단계
1. /opt/fixtures/msa/monolith.py 를 127.0.0.1:8101 에 띄우고 GET /health 가 200 을 주게 한다.
2. 모놀리스의 라우트를 조사해 /root/msa/seams.txt 에 한 줄에 하나씩 경로 도메인 형식으로 적는다. orders 와 inventory 두 도메인이 모두 등장해야 하고 최소 4줄이어야 한다.
3. /root/msa/contract.json 을 만든다. 최상위 키는 orders 와 inventory 두 개이고, 각각 port(정수)와 paths(문자열 배열)를 가진다. orders 는 8103, inventory 는 8102 이다.
4. /root/msa/inventory_svc.py 를 만들어 127.0.0.1:8102 에 띄운다. GET /stock/SKU-1 이 {"sku":"SKU-1","qty":<정수>} 를 준다.
5. /root/msa/orders_svc.py 를 만들어 127.0.0.1:8103 에 띄운다. POST /orders 는 {"sku":"SKU-1","qty":2} 를 받아 재고 서비스에 물어본 뒤 충분하면 201 과 order_id, 모자라면 409 를 준다.
6. orders_svc.py 소스에 /opt/fixtures/msa/inventory.json 같은 재고 데이터 경로가 없어야 하고, 대신 8102 호출이 있어야 한다.
7. /root/msa/parity.sh 를 만든다. 같은 요청을 모놀리스(8101)와 새 주문 서비스(8103)에 보내 상태코드와 판정이 같으면 PARITY OK 를 출력한다. 실행 결과를 /root/msa/parity.out 에 남긴다.
8. /root/msa/decision.md 에 ## 쪼갠 이유 와 ## 쪼개지 말았어야 할 이유 두 제목을 넣고 각각 30자 이상 쓴다.
참고
- 백그라운드 기동:
nohup python3 파일.py > /root/msa/파일.log 2>&1 & - 포트 확인:
ss -ltnp | grep 810 - 흔한 실수 1: 새 서비스가 재고 JSON 파일을 그대로 열어 읽는 것 — 그건 분리가 아닙니다.
- 흔한 실수 2: 응답 JSON 의 키 이름을 바꿔 버리는 것 — 계약을 먼저 적은 이유가 그것입니다.
단계 8개
- 모놀리스 띄우고 기준선 잡기
- 이음매(seam) 목록 만들기
- 두 서비스의 계약 고정하기
- 재고 서비스 분리하기
- 주문 서비스 분리하기
- 데이터 소유권 분리 증명하기
- 모놀리스와 응답 동등성 비교하기
- 분리 판단 기록 남기기