Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
# 트레이드오프 위에서의 아키텍처 선택

## 1 ~ 3장
---

## chapter 1 - '베스트 프랙티스'가 없다면?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

문서 전반의 통일성을 위해 장(Chapter) 제목 표기를 chapter 1과 같은 영문 대신 1장과 같이 한글로 수정하는 것을 제안합니다. 43행, 59행의 chapter 2, chapter 3도 함께 수정하면 좋겠습니다.

Suggested change
## chapter 1 - '베스트 프랙티스'가 없다면?
## 1장 - '베스트 프랙티스'가 없다면?


> 정답은 없다. 다만 트레이드오프만 있을 뿐이다.

우리는 늘 정답을 찾는다. 나 또한 그렇다.
하지만 인생이 그렇듯, 소프트웨어 설계에도 절대적인 정답은 없다.
존재하는 것은 언제나 **장점과 단점**, 그리고 그 사이에서의 **선택**뿐이다.

아키텍처 설계 역시 마찬가지다.
"어떤 구조가 가장 좋은가?"가 아니라,
**"지금 이 시점의 제약과 상황에서 무엇이 가장 합리적인 선택인가?"** 를 고민하는 문제다.

그래서 이 책은 정답을 주기보다는,
그 선택을 하기 위해 필요한 **사고의 도구들**을 설명한다.

### 이 책에서 반복적으로 등장하는 키워드들

- coupling / cohesion
- component 경계
- sync / async
- orchestration / choreography
- atomicity
- contract

이 단어들은 각각 따로 보면 어려울 수 있지만,
결국은 **"무엇을 함께 묶고, 무엇을 분리할 것인가"** 라는 질문으로 수렴한다.

책에서 다루는 *한빛가이버* 사례를 읽으면서,
나는 지난 5년간 내가 겪어온 MSA 전환 과정과 굉장히 유사하다는 느낌을 받았다.
정답을 찾아 적용하기보다는,
트래픽·조직·장애·운영이라는 현실 속에서
계속해서 **트레이드오프를 선택해 온 과정**에 더 가까웠기 때문이다.

이 챕터는
"베스트 프랙티스를 알려주는 장"이 아니라,
**이후 챕터들을 어떤 관점으로 읽어야 하는지를 정리해 주는 장**이라고 느꼈다.

## chapter 2 - 아키텍처 퀀텀

> MSA는 '유행'이 아니라, 현재 시스템의 제약과 이해를 바탕으로 선택해야 하는 결과다.

나의 경험을 예로 들면, 처음에는 다들 그렇듯이 레이어드 모놀리식으로 시작했다.
그 이후 MSA를 목표로 점진적인 전환을 시도하고 있다.

아직은 DB를 완전히 분리하지 못해, 엄밀한 의미의 MSA를 적용했다고 보기는 어렵다.
다만 향후 DB 분리와 서비스 분리를 가능하게 만들기 위해, 미리 헥사고날 아키텍처와 이벤트 기반 아키텍처를 적용하는 방향으로 설계를 진행 중이다.
(이벤트 기반 아키텍처의 경우, 늘어나는 트래픽 대응이 주된 목적이다.)

또한 비동기 통신을 위한 보상 처리로 Saga 패턴도 함께 적용하고 있다.

이처럼 각자의 상황과 제약에 맞게 아키텍처를 선택하는 것이 중요하다고 생각한다.
MSA가 무조건 좋은 것도 아니고, 모놀리식이 무조건 나쁜 것도 아니다.

## chapter 3 - 아키텍처 모듈성

> 아키텍처 별 성격 비교

유지 보수성, 시험성, 확장성, 가용성/내고장성 관점에서 보면
모놀리식 < 서비스 기반 < MSA 순으로 점수가 매겨지는 흐름이 나온다.

### 정리

아키텍처 모듈성을
유지 보수성, 시험성, 확장성, 가용성/내고장성 관점에서 비교하면
일반적으로 **모놀리식 < 서비스 기반 < MSA** 순으로 평가가 높아진다.

이 결과는 "아키텍처의 우열"이라기보다는,
**결합을 얼마나 잘 분리했는가**에 대한 평가에 가깝다고 느꼈다.

- 모놀리식은 변경·장애·확장의 범위가 하나로 묶여 있어
규모가 커질수록 리스크가 증폭되기 쉽다.
- 서비스 기반 아키텍처는 일정 수준의 분리를 제공하지만,
공통 로직과 동기 호출 체인이 늘어나면 다시 결합도가 높아진다.
- MSA는 서비스별 DB 분리와 비동기 통신을 전제로 할 때,
변경 영향 최소화, 독립 확장, 장애 격리 측면에서 가장 큰 이점을 가진다.

다만 이 점수표는
**MSA를 '제대로 운영할 수 있다는 전제'가 붙은 결과**라는 점이 중요하다.
운영 성숙도, 관측성, 재처리, 계약 관리가 뒷받침되지 않으면
높은 점수는 오히려 높은 복잡도로 돌아올 수 있다.

결국 이 비교는
"어떤 아키텍처가 더 낫다"를 말하기보다는,
**어떤 트레이드오프를 선택할 준비가 되어 있는가**를 묻는 기준이라고 생각한다.

### 논의사항

1. **서비스 기반 아키텍처는 ‘과도기’인가, ‘최종 형태’인가?**
서비스 기반은 MSA로 가기 위한 단계인가?
아니면 **조직·트래픽·운영 역량이 맞으면 충분히 '최종 형태'** 가 될 수 있는가?
Comment on lines +93 to +95
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

책의 저자가 얘기하는 방향이라면 과도기일텐데, 특정 회사의 특정 조직은 최종 형태가 될 수 있다고도 생각합니다.
회사마다 비용과 수익에 따라 서비스 기반 아키텍처가 큰 문제가 없다고 하면 그대로 최종 형태일 수도 있다는 것이죠.
진짜 초기 스타트업이라면 작은 모놀리식도 최종 형태로 굳어져서 그대로 몇 년 동안 운영할 수도 있는 거고요.

책의 내용만 이해한다면 마이크로서비스 아키텍처를 지향해야 하겠지만
그렇지 않은 경우라고 해도 최종 형태로 판단하고 결정해도 문제는 없을 거라고 봅니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

책에 따르면 서비스 기반 아키텍처는 확장성 3점, 탄력성 2점이고, MSA는 확장성, 탄력성 모두 5점이라고 되어있습니다.
극단적인 확장성, 탄력성이 필요하지 않다면 서비스 기반 아키텍처도 충분히 최종 형태가 될 수 있다고 생각합니다.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 생각하는 제품 or 어플리케이션의 방향성이 아키텍처의 추구하는 방향과 맞다면 현재 시점에서는 최종 형태로 불릴 수 있겠으나 추후 어떤 식으로든 제품이 확장되고 복잡해지거나 새로운 아키텍처가 대두된다면 .. 다시 과도기적 형태로 돌아가지 않을까 생각되었는데 다른 분들 의견은 또 다르네요


2. **MSA의 장점을 얻기 위해 반드시 필요한 전제는 무엇인가?**
DB 분리 없이도 MSA를 했다고 말할 수 있는가?
Comment on lines +97 to +98
Copy link
Collaborator

@TaeHyoungKwon TaeHyoungKwon Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSA의 장점을 얻기 위해 반드시 필요한 전제는 무엇인가?

  • MSA를 해야한다 말아야한다의 결정에서 가장 먼저 고려해야할 전제는 장애 격리 라고 생각합니다. 예를 들면, admin의 슬로우 쿼리가 많이 발생해서, 결제쪽에서 에러가 난다, 이벤트 트래픽으로 인해 서버가 죽어서, 고객이 앱에 접속조차 못한다 등
  • 그 외에는 여러가지 사유가 있을텐데, 회사의 사정에 맞게 알아서, 판단하면된다고 생각하는데, 기본적으로는 유지보수를 할 수 있는 인원이 반드시 갖춰줘야한다고 생각합니다 개발자는 2 ~ 3명인데 MS가 15~20개? 이러면 안되겠죠

Copy link
Collaborator

@TaeHyoungKwon TaeHyoungKwon Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DB 분리 없이도 MSA를 했다고 말할 수 있는가?

  • 일반적으로는 MSA는 DB 분리가 전제 됩니다 그래서, MSA를 적용할 때는 각 MS 마다 분리된 DB들의 정합성과 무결성을 어떻게 맞출 것인가에 대한 고민이 반드시 수반이 됩니다 그래서 DB분리 없이는 MSA를 했다고 말할 수 없습니다(책 내용 기준으론, 서비스 기반 아키텍쳐를 적용했다고 보는게 맞을거 같습니다)
스크린샷 2026-01-05 오전 12 17 43
  • 그러나, 제 개인적으로는 현재 우리 회사 아키텍쳐가 MSA이냐 아니냐? 그래서 MSA를 해봤냐 안해봤냐를 어떤 특정기준으로 판단하는 것은 의미없는 논쟁이라고 생각하는 편 입니다. 왜냐하면, 사람마다, 회사마다 다 이해하는 수준도 다르고, 기준도 다르기 때문입니다
  • 그래서, 제 개인적으로는 MSA를 했냐 안했냐? 로 하는 것보다는 좀 더 추상적으로, 분산 환경에서 서버를 설계하고 운영해보았느냐? 로 말하는게 더 명확하지 않을까 생각되고, 그 기준에선, DB를 각 MS마다 가지냐 안가지냐는 중요한 문제는 아니라고 생각하는 편 입니다(모든 분산 환경에서의 서버들이 DB를 가져야하는 것은 아니기 때문 - ex) aws lambda)

Comment on lines +97 to +98
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 역시 책의 내용대로 한다면 서비스 개수 만큼 아키텍처 퀀텀의 개수가 나와야 하고 각 서비스는 아키텍처 특성이 모두 같을 수도 있지만 같지 않게 해야 한다 일 것 같습니다.

정리하면

  • 특정 도메인의 비즈니스 요구사항을 처리하는 작은 서비스
  • 그 서비스만 사용하는 DB
  • 서비스별 아키텍처 특성을 살려 설계

일 것 같네요.


DB의 분리 없이 MSA를 했느냐는 책을 읽었다면 "아니오"라고 해야 맞을 것 같습니다.
이 주제는 이후에 데이터베이스 관련 챕터를 읽고 난 후 논의 주제로 또 나올 것 같아서
이번 모임 때 논의 주제로 해보면 재밌을 것 같기도 합니다.
왜냐하면 나중에 데이터베이스 관련 내용을 읽고 난 후에도 각자 생각의 변화가 있을 것인가? 에 대해 궁금하기 때문이기도 합니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSA의 장점을 얻기 위해 반드시 필요한 전제는 무엇인가?

가장 중요한건 **현재의 상황(환경)**이겠지만.. MSA를 충분히 운영 가능한 환경(인원, 지원 등)이라면 아래의 요소들이 필수 전제라고 생각합니다.

  • 각 서비스가 다른 서비스와 상관없이 독립적인 배포가 가능할 것
  • 데이터베이스의 분리
  • 이를 위한 명확한 도메인 식별/분리/설계



> 아래 내용은 정리나 결론을 위한 글은 아니다.
> 혹시 비슷한 규모의 시스템을 운영하면서
> 다른 팀은 어떻게 하고 있는지 궁금한 사람이 있다면,
> 참고가 될 수 있을 것 같아 남겨둔 개인적인 경험 기록이다.

### 경험 사례 – 내가 겪은 아키텍처 선택의 흐름

#### 여러 아키텍처를 거치며 느낀 점

**레이어드 모놀리스**는 전통적이고 빠르게 시작하기에 좋았다.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

47행 등 다른 곳에서는 '모놀리식'으로 표기되어 있습니다. 용어의 일관성을 위해 '모놀리스'를 '모놀리식'으로 수정하는 것이 좋겠습니다.

Suggested change
**레이어드 모놀리스** 전통적이고 빠르게 시작하기에 좋았다.
**레이어드 모놀리식** 전통적이고 빠르게 시작하기에 좋았다.

하지만 규모가 커질수록 도메인 경계가 흐려지고,
작은 변경이 예상보다 넓은 영역에 영향을 주는 경험을 자주 하게 됐다.

**모듈러 모놀리스**는 도메인 단위로 모듈을 나누면서
변경 영향 범위를 줄이는 데는 분명 도움이 됐다.
다만 시간이 지나면서
"이건 어느 모듈 책임이지?" 같은 애매한 지점이 생기기 시작했고,
그 순간부터 경계를 지키는 일이 생각보다 어렵다는 걸 체감했다.

**마이크로커널 아키텍처**는
확장 축(기능/전략)이 반복적으로 추가될 때는 꽤 매력적이다.
예를 들어 PG 연동처럼
결제/취소/중단(Abort) 흐름이 유사한 기능이 계속 늘어나는 경우에는
플러그인이나 전략 패턴으로 분리할 가치가 있다.
다만 실제로 운영해보니,
생각보다 이렇게 반복적으로 확장되는 영역은 많지 않았고
그 외의 영역에서는 과설계가 되기 쉽다고 느꼈다.

---

#### 결국 선택한 방향: 서비스 기반 + 헥사고날

서비스 기반 아키텍처는
팀을 나누고 서비스를 분리하는 데 분명한 장점이 있다.
하지만 실제로 운영해보면
공통 로직이 생기는 순간부터 선택이 어려워진다.

- 그냥 복붙할지
- 공용 라이브러리로 묶을지
- 아니면 공통 서비스를 하나 더 만들지

이 선택을 매번 고민하게 된다.

특히 서비스 간 동기 호출이 늘어날수록,
장애가 전파되고 배포가 서로 엮이는 경험을 여러 번 했다.
이 지점이 서비스 기반 아키텍처에서
가장 크게 체감한 한계였다.

그럼에도 불구하고,
현재의 조직 규모와 트래픽을 고려하면
서비스 단위로 나누는 선택 자체는 피하기 어렵다고 판단했다.
그래서 내 기준에서의 질문은
**"나눌 것인가?"가 아니라 "어디까지 나눌 것인가?"** 였다.

그 결과 나는
서비스 기반 구조를 유지하되,
헥사고날 아키텍처를 적용해
서비스 내부의 도메인 경계를 최대한 명확히 하려고 했다.
그리고 공통 로직은 정말 불가피한 경우에만
내부 모듈이나 라이브러리로 제한하고,
도메인 로직이 공통으로 새어나가지 않도록 의식적으로 막고 있다.

---

### 그리고 EDA

EDA를 도입한 지점은 **결제 이후**다.
결제 자체는 짧고 확실하게 끝내고,
결제 이후에 따라오는 후속 작업들을
동기 호출로 묶지 않기 위해 Kafka 기반 이벤트로 분리했다.

#### 이벤트 발행 (결제 서비스)

결제가 완료되면 Kafka로 이벤트를 발행한다.
이 이벤트에는 대략 다음 정보가 담긴다.

- paymentSeq (결제 식별자)
- amount (금액)
- item 정보 (상품 / 구성 / 수량 등)

중요한 점은
"무엇을 해라"가 아니라
**"결제가 완료되었다"라는 사실을 발행**한다는 것이다.

#### 팀1 컨슘: Timeline 적재

팀1은 이 이벤트를 컨슘해서
결제 건을 Timeline에 적재한다.
이 작업은 결제의 성공/실패와 운명을 같이할 필요가 없고,
지연되더라도 나중에 따라잡을 수 있기 때문에
비동기 방식이 잘 맞았다.

#### 팀2 컨슘: 적립 계산 및 반영

팀2는 동일 이벤트를 컨슘한 뒤,
자기 정책에 따라 적립 금액을 계산하고 적립을 반영한다.

적립은 정책·이벤트·프로모션에 따라 변수가 많고,
결제 서비스가 직접 알고 있어야 할 이유가 없다고 판단했다.
오히려 결제 플로우에 섞이면
변경 영향 범위만 커진다.
그래서 계산과 반영의 책임을 아예 분리했다.
Comment on lines +185 to +202
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[질문]

  • 여기서 팀1, 팀2는 결제완료 이벤트 컨슘 이후, 수행해야할 비즈니스 로직을 팀별로 나누어서 책임을 가지도록 하신걸로 이해하면 될까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 그렇습니다. 좀 더 정확히 말씀드리면

내역의 경우, 예~~전에는 여러 팀(쇼핑, 외부결제, 디지털컨텐츠)에 나눠진 결제 데이터를 각각 조회하여 유저에게 보여줬는데,
내역팀이 만들어면서 카프카로 데이터를 내역팀에 주게 되었고,

적립의 경우, 서비스 파트에서 적립율을 주고, 결제 파트에서 계산 및 적립 요청을 하던 구조였는데,
적립파트에서 적립율 관련 어드민을 신설하여 서비스별 적립율을 작성하고 결제 완전 종료 후, 카프카로 데이터 주면 적립율계산 및 적립 로직을 가져갔습니다.


---

#### EDA를 통해 얻은 효과

- 결제 서비스는 결제 자체에만 집중할 수 있었다
- 동기 호출 체인을 끊으면서 더 빠른 결제 및 더 많은 처리량을 달성할 수 있었다
- 후속 작업은 컨슈머 확장으로 처리량을 맞추고,
피크 트래픽은 큐가 흡수하도록 만들 수 있었다

#### 미래 수정할 점

현재는 **결제 완료 이벤트**를 타 팀에서 직접 컨슘해
내역 적재나 포인트 작업까지 처리하고 있다.

하지만 앞으로는 다음 형태로 바꿀 예정이다.

- 결제 서비스는 **결제 완료(Fact)** 이벤트만 발행한다.
- 해당 토픽을 컨슘하는 서비스가
- **내역 발행 Command**
- **포인트 적립 Command**
를 각각 발행한다.

이렇게 하면 내역은 쌓였는데 포인트 적립이 누락된 경우에도
Admin을 통해 **포인트 적립 Command만 재발행**하는 형태로 보상이 가능해진다.

#### 운영하면서 중요했던 포인트

- 이벤트 중복/재처리는 전제로 두고 멱등하게 설계한다
- 재처리를 항상 가능하게 만든다
- 추적을 위해 requestUuid 같은 식별자를 이벤트에 포함한다
- 사내에 FDC(financial Data Center)가 존재하고, 매일 bulk로 사내 전체 DB를 조회하여 적재한다. 그리고 매일 배치를 돌려서 누락된 적립이 있는지 확인하고, 존재한다면 노티 이메일을 보내준다. 따라서
재처리가 가능하다. 이것이 운영에서 가장 중요한 포인트였다.
Comment on lines +234 to +235
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

이 문장은 여러 절차를 한 번에 설명하고 있어 다소 길고 복잡하게 느껴집니다. 가독성을 높이기 위해 아래와 같이 내용을 분리하여 간결하게 다듬는 것을 제안합니다.

Suggested change
- 사내에 FDC(financial Data Center)가 존재하고, 매일 bulk로 사내 전체 DB를 조회하여 적재한다. 그리고 매일 배치를 돌려서 누락된 적립이 있는지 확인하고, 존재한다면 노티 이메일을 보내준다. 따라서
재처리가 가능하다. 이것이 운영에서 가장 중요한 포인트였다.
- 재처리를 보장하는 운영 환경이 핵심이었습니다. 사내 FDC(Financial Data Center)가 매일 DB 전체를 bulk로 적재하고, 일일 배치가 누락된 적립을 확인하여 알림을 보냅니다. 이 덕분에 안정적인 재처리가 가능했습니다.