diff --git "a/ch17_\353\247\210\354\235\264\355\201\254\353\241\234\354\204\234\353\271\204\354\212\244_\354\225\204\355\202\244\355\205\215\354\262\230_\354\212\244\355\203\200\354\235\274/ch17_max.md" "b/ch17_\353\247\210\354\235\264\355\201\254\353\241\234\354\204\234\353\271\204\354\212\244_\354\225\204\355\202\244\355\205\215\354\262\230_\354\212\244\355\203\200\354\235\274/ch17_max.md" new file mode 100644 index 0000000..c2a4552 --- /dev/null +++ "b/ch17_\353\247\210\354\235\264\355\201\254\353\241\234\354\204\234\353\271\204\354\212\244_\354\225\204\355\202\244\355\205\215\354\262\230_\354\212\244\355\203\200\354\235\274/ch17_max.md" @@ -0,0 +1,172 @@ +# 17장. 마이크로서비스 아키텍처 스타일 + +## 17.1 역사 + +1. 아키텍터 스타일의 명명 + - 기존 스타일은 반복 패턴 발견 후 명명 + - 소프트웨어 생태계 변화로 자연스럽게 결정됨 +2. 마이크로서비스의 시작 + - 2014년, 마틴 파울러와 제임스 루이스의 블로그 Microservice로 확산 +3. DDD와 경계 콘텍스트 + - 도메인 주도 설계(DDD)의 영향을 받음 + - 경계 콘텍스트: 내부 요소만 결합, 외부와 디커플링 유지 +4. 재사용 vs 디커플링 + - 재사용은 커플링 유발 + - 마이크로서비스는 디커플링을 위해 중복을 우선 + +## 17.2 토폴로지 + +![스크린샷 2024-11-25 오후 9.49.59.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/fef31b45-5ba1-48ad-8b81-f071e47abdeb/de54601f-931a-4797-9535-af0c27883d49/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-11-25_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_9.49.59.png) + +- 마이크로서비스는 단일 목적만 수행하며, 다른 분산 아키텍처보다 서비스 규모가 작음. +- 각 서비스는 독립적으로 작동하기 위해 필요한 데이터베이스 및 종속 컴포넌트를 자체적으로 포함함. + +## 17.3 분산 + +1. 마이크로서비스와 분산 아키텍처 + - 서비스는 자체 프로세스로 실행되며 가상 머신과 컨테이너로 발전 + - 독립된 프로세스를 통해 공유 인프라에서 발생하는 리소스 제약과 잘못된 분리 문제를 해소 +2. 기술 발전의 역할 + - 클라우드 리소스와 컨테이너 기술로 도메인 및 운영 레벨의 디커플링이 현실화 +3. 성능의 한계 + - 네트워크 호출과 보안 검증으로 인해 성능 저하 발생 + - 서비스 세분도 결정이 중요 +4. 트랜잭션 경계 관리 + - 트랜잭션이 서비스 경계를 넘지 않도록 설계 필요 + - 성공의 핵심은 적절한 서비스 세분화 + +## 17.4 경계 콘텍스트 + +1. 경계 콘텍스트 개념 + - 각 서비스는 도메인이나 워크플로를 모델링하며, 필요한 모든 요소(클래스, 데이터베이스 스키마 등)를 포함 + - 커플링을 최소화하기 위해 중복을 선호 +2. 도메인 분할의 철학 + - 마이크로서비스는 도메인 도는 서브도메인을 독립적으로 구현 + - 도메인 주도 설계(DDD)의 논리적 개념을 물리적으로 실현한 결과물 + +### 17.4.1 세분도 + +1. 세분화의 문제점 + - 서비스를 지나치게 잘게 나누면 서비스 간 통신 복잡성이 증가. + - 마이크로서비스는 이름일 뿐, 세분화를 지시하는 명령은 아님 +2. 서비스 경계 설정의 가이드라인 + - 목적 : 각 서비스는 도메인을 기반으로 설계하며, 응집력을 높이고 핵심 기능을 담당 + - 트랜잭션: 여러 엔티티가 관여하는 트랜잭션은 서비스 경계 설정의 단서가 될 수 있음. + - 코레오그래피 : 서비스 간 통신이 과도하면 더 큰 단위로 통합 고려 +3. 설계 접근법 + - 적절한 세분도는 반복적 이터레이션을 통해 다듬어야 함 + - 초기 설계가 완벽할 수 없으므로 다양한 옵션을 실험하며 최적화 + +### 17.4.2 데이터 격리 + +1. **데이터 격리의 필요성** + - 마이크로서비스는 공유 데이터베이스나 스키마 등 통합 지점을 없애고 데이터를 격리. + - 서비스 세분화 시 데이터 격리를 고려해야 하며, 단순히 데이터베이스 엔티티에 기반한 설계는 지양. +2. **데이터 분산 접근법** + - 도메인별로 **진실 공급원(Single Source of Truth)**을 정의하거나, 데이터베이스 복제와 캐시를 활용. + - 데이터는 아키텍처 전반에 분산되어야 함. +3. **데이터 격리의 장점** + - 팀별로 독립적인 데이터베이스 및 스토리지 도구 선택 가능. + - 다른 팀에 영향을 주지 않고 상황에 맞게 적합한 데이터베이스와 의존성을 선택 가능. + - 구현 세부 사항에 얽매이지 않는 유연성 제공. + +### 17.5 API 레이어 + +1. **API 레이어의 역할** + - 여러 시스템 컨슈머 간의 **프록시** 역할로 간접화하거나, 네이밍 서비스 등 운영 장치와 연결 가능. + - 다양한 용도로 활용되지만 **비즈니스 로직**은 API 레이어가 아닌 경계 콘텍스트 내부에서 처리해야 함. +2. **철학적 원칙** + - API 레이어를 **중재자**나 **오케스트레이션 도구**로 사용하면 마이크로서비스의 철학에 어긋남. + - 마이크로서비스는 **도메인 분할**에 초점을 맞추며, 기술 분할과 차별화됨. + +## 17.6 운영 재사용 + +1. **운영 관심사 분리** + - 모니터링, 로깅, 회로 차단기 등은 서비스별로 운영이 일관되게 관리되어야 함. + - **사이드카 패턴**: 운영 관심사를 별도의 사이드카 컴포넌트로 처리해 각 서비스에 공통적으로 적용. +2. **사이드카 패턴의 장점** + - 공유 인프라팀이 사이드카를 관리 및 업그레이드하며 일관성을 유지. + - 사이드카는 서비스 메시를 통해 로깅, 모니터링 등을 통합 제어하며 공통 인터페이스 제공. +3. **서비스 메시와 디스커버리** + - **서비스 메시**: 모든 마이크로서비스를 하나의 네트워크로 연결해 공통 운영을 제어하는 콘솔 역할. + - **서비스 디스커버리**: API 레이어에서 요청을 관리하며, 확장성과 탄력성을 지원. + - 디스커버리 도구를 통해 요청 빈도를 모니터링하고 필요에 따라 서비스 인스턴스를 자동 확장. + +## 17.7 프런트엔드 + +1. **마이크로서비스와 유저 인터페이스** + - 마이크로서비스는 유저 인터페이스와 백엔드의 분리를 선호하지만, 실용적인 이유로 완전한 분리가 어려움. + - 초기 비전에서는 유저 인터페이스가 DDD 원칙에 따라 경계 콘텍스트의 일부로 포함되었으나, 외부 제약으로 인해 실현이 어려움. +2. **유저 인터페이스 스타일** + - **모놀리식 프런트엔드**: 단일 유저 인터페이스가 API 레이어를 통해 호출되어 다양한 형태의 웹, 모바일, 데스크톱 애플리케이션을 처리. + - **마이크로프런트엔드**: 유저 인터페이스를 백엔드 서비스에서 동기적으로 세분화하고 격리. 각 서비스는 자기 서비스에 해당하는 UI를 내보내며, 프런트엔드는 이를 조정. + - **마이크로프런트엔드 구현**: 리액트와 같은 컴포넌트 기반 웹 프레임워크나 이를 지원하는 오픈 소스 프레임워크를 사용하여 구현. + +## **17.8** 통신 + +1. **세분도와 통신 스타일** + - 마이크로서비스를 구축할 때 아키텍트와 개발자는 데이터 격리와 통신 방식을 적절히 세분화하려고 노력. + - 올바른 통신 스타일을 선택하는 것이 서비스 디커플링에 중요한 영향을 미친다. +2. **동기 vs 비동기 통신** + - **동기 통신**: 호출자가 수신자의 응답을 기다리는 방식. + - **비동기 통신**: 이벤트와 메시지를 활용하며, 주로 이벤트 기반 아키텍처를 사용한다. + - **비동기 통신 패턴**: 브로커 패턴과 중재자 패턴은 코레오그래피 및 오케스트레이션 패턴으로 나타난다. +3. **프로토콜 인지 이종 간 상호 운용성** + - **프로토콜 인지**: 서비스는 다른 서비스를 호출할 때 사용하는 프로토콜을 알고 있어야 하며, 아키텍트는 이를 표준화해야 한다. + - **이종**: 마이크로서비스는 각기 다른 기술 스택을 사용할 수 있으며, 이는 환경에 따라 다를 수 있다. + - **상호 운용성**: 여러 서비스가 서로 호출하며 협력하는 과정이 중요하다. + +### 17.8.1 코레오그래피와 오케스트레이션 + +1. **코레오그래피와 브로커 이벤트 기반 아키텍처** + - 코레오그래피는 중앙 중재자 없이 각 서비스가 독립적으로 다른 서비스를 호출. + - 서비스 간 분리된 이벤트를 사용하여 경계 콘텍스트 철학을 따름. + - 예시: 유저가 요청 시, 필요한 정보를 다른 서비스에서 호출해 보충. +2. **도메인/아키텍처 동형성** + - 아키텍처 스타일이 문제에 적합한지 평가하는 특성. + - 마이크로서비스는 브로커 이벤트 기반 아키텍처와 유사함. +3. **중재자 패턴** + - 전역 중재자가 없으므로, 로컬 중재자를 두어 서비스 호출을 조정. + - 예시: 중재자가 다른 서비스를 호출해 필요한 데이터를 조합. +4. **복잡한 비즈니스 프로세스와 중재자 역할** + - 프런트 컨트롤러 패턴을 사용해 하나의 서비스가 여러 타 서비스를 조정. + - 서비스 복잡도가 증가하지만, 조정 역할이 집중됨. +5. **오케스트레이션** + - 비즈니스 프로세스를 다룰 때 오케스트레이션을 사용해 중재자가 서비스를 조정. + - 서비스 간 커플링을 생성하지만, 중재자가 조정 작업을 전담. + +### 17.8.2 트랜잭션과 사가 + +1. **트랜잭션과 마이크로서비스** + - 마이크로서비스는 극도의 디커플링을 추구하지만, 여러 서비스에 걸친 트랜잭션을 조정하는 문제는 아키텍트에게 큰 도전. + - 트랜잭션을 여러 서비스에 걸쳐 사용하면 마이크로서비스 아키텍처의 디커플링 원칙에 위배되며, 동적 커네이선스 문제가 발생할 수 있음. + - 트랜잭션 경계는 서비스 세분도를 가늠할 수 있는 지표로 활용되므로, 불필요하게 트랜잭션으로 서비스를 엮기보다는 세분도를 적절히 조정하는 것이 중요. +2. **사가 패턴 (Saga Pattern)** + - 분산 트랜잭션을 처리하기 위한 패턴으로, 중재자가 각 서비스 호출을 조정하고 트랜잭션의 성공/실패를 기록. + - 트랜잭션의 한 부분이 실패하면, 중재자는 이전에 성공한 부분을 되돌리는 보상 트랜잭션을 실행. + - **보상 트랜잭션**: 실패한 트랜잭션을 되돌리기 위해 각 작업에 대한 언두 로직을 작성. +3. **트랜잭션 설계의 복잡성** + - 사가 패턴을 사용하면 네트워크 트래픽이 많이 발생하고, 비동기 요청과 보류된 트랜잭션 상태로 인해 설계가 복잡해짐. + - 트랜잭션 작업마다 언두 로직을 개발해야 하므로, 설계, 구현, 디버깅에 큰 부담이 될 수 있음. + - 트랜잭션을 걸기보다는 세분도를 바로잡는 것이 기본 원칙이지만, 예외적인 경우에만 사가 패턴을 사용하는 것이 권장됨. + +### 17.9 아키텍처 특성 등급 + +1. **마이크로서비스 아키텍처 특성** + - **별점 1개**: 마이크로서비스 아키텍처는 자동화 배포, 시험성, 그리고 현대 엔지니어링 프랙티스를 매우 잘 지원. + - **별점 5개**: 확장성, 탄력성, 진화성 등 주요 강점으로, 마이크로서비스는 분산 시스템에서 높은 내고장성, 신뢰성을 지원. +2. **확장성 및 탄력성** + - 마이크로서비스 아키텍처는 고도로 분리된 작은 배포 단위를 통해 빠르게 변화하는 시스템을 지원. + - **확장성**: 마이크로서비스는 성능 문제가 발생할 수 있지만, 분산 아키텍처는 여러 서비스의 확장을 통해 문제를 해결. + - **탄력성**: 운영 자동화 및 지능적 통합을 통해 아키텍처의 탄력성을 강화. +3. **성능 및 통신** + - 분산 아키텍처에서의 성능 오버헤드는 주로 잦은 네트워크 호출과 보안 체크에 의한 것. 이를 해결하기 위해 데이터 캐시, 데이터 복제 등의 기술이 사용됨. + - **네트워크 호출 감소**: 과도한 네트워크 호출을 줄이고 성능을 개선하기 위해 코레오그래피 스타일을 선호. +4. **도메인 중심 아키텍처** + - 마이크로서비스는 각 서비스의 경계와 도메인이 일치해야 하며, 도메인 중심적인 아키텍처를 지향. + - **디커플링**: 고도의 디커플링을 추구하여, 시스템의 변화에 유연하게 대응할 수 있음. +5. **마이크로서비스의 도전** + - 마이크로서비스 아키텍처는 디커플링을 극대화하려는 철학으로, 이를 잘 구현하면 엄청난 이점을 얻을 수 있지만, 그 과정에서 복잡성도 증가. + - 규칙을 이해하고 이를 지능적으로 깨뜨릴 수 있어야 아키텍처의 이점을 극대화할 수 있음. + +마이크로서비스 아키텍처는 유연성과 확장성을 제공하지만, 성능 최적화와 트랜잭션 관리 등 복잡한 도전 과제를 동반하므로 신중한 접근이 필요하다. diff --git "a/ch18_\354\265\234\354\240\201\354\235\230_\354\225\204\355\202\244\355\205\215\354\262\230_\354\212\244\355\203\200\354\235\274_\354\204\240\354\240\225/ch18_max.md" "b/ch18_\354\265\234\354\240\201\354\235\230_\354\225\204\355\202\244\355\205\215\354\262\230_\354\212\244\355\203\200\354\235\274_\354\204\240\354\240\225/ch18_max.md" new file mode 100644 index 0000000..56f10ff --- /dev/null +++ "b/ch18_\354\265\234\354\240\201\354\235\230_\354\225\204\355\202\244\355\205\215\354\262\230_\354\212\244\355\203\200\354\235\274_\354\204\240\354\240\225/ch18_max.md" @@ -0,0 +1,82 @@ +# 18장. 최적의 아키텍처 스타일 선정 + +## 18.1 아키텍처 유행은 계속 변한다. + +1. **과거의 경험** + - 아키텍트는 과거의 경험을 바탕으로 아키텍처 설계를 합니다. 과거에 겪었던 결함이나 단점은 새로운 설계에 반영되며, 이전 시스템에서의 문제를 해결하려는 노력이 현재의 아키텍처를 형성하게 된다. +2. **생태계의 변화** + - 소프트웨어 개발 생태계는 끊임없이 변화하고 있으며, 예측하기 어려운 변화가 일어난다. 예를 들어, 과거에는 쿠버네티스 같은 기술이 거의 알려지지 않았지만 지금은 대세가 되어 가고 있다. 이러한 변화는 예상치 못한 도구와 기술로 아키텍처에 영향을 미칠 수 있다. +3. **새로운 기능과 패러다임 전환** + - 새로운 기능의 출현은 아키텍처에 큰 변화를 일으킬 수 있다. 예를 들어, 도커와 같은 컨테이너 기술이 등장하면서 소프트웨어 개발에 혁신을 가져왔다. 새로운 도구와 기능들은 기존 시스템을 완전히 대체하기보다는 점진적으로 아키텍처의 패러다임을 변화시킨다. +4. **변화의 속도 가속화** + - 생태계의 변화는 점점 더 빨라지고 있으며, 새로운 도구와 엔지니어링 프랙티스는 빠르게 발전하고 있다. 아키텍트는 이러한 지속적인 변화를 따라가며, 새로운 설계와 기능을 도입하는 데 있어 유연함과 빠른 대응이 중요해졌다. + +## 18.2 결정 기준 + +### 1. **도메인 이해** + +- 아키텍트는 시스템 설계 전에 해당 도메인에서 중요한 요소들을 파악해야 한다. 도메인 전문가가 아니더라도 최소한 해당 도메인에 대한 기본적인 이해는 필요하다. 도메인의 특성이 아키텍처 설계에 큰 영향을 미치기 때문에 아키텍트는 그 부분을 충분히 고려해야 한다. + +### 2. **구조에 영향을 미치는 아키텍처 특성** + +- 아키텍트는 시스템의 요구사항을 충족시키기 위해 도메인 및 외부 요소에 맞는 아키텍처 특성을 정의해야 한다. 데이터 아키텍처, 조직 내 구조적 요소, 외부 팩터 등을 고려하여 설계해야 한다. + +### 3. **데이터 아키텍처** + +- 데이터베이스 설계는 아키텍트와 DBA의 협업을 필요로 하다. 데이터 아키텍처는 시스템의 성능에 중요한 영향을 미치므로, 새로운 시스템이 기존의 데이터 아키텍처와 어떻게 상호작용할지 충분히 파악해야 한다. + +### 4. **조직 문제** + +- 조직 내 환경도 아키텍처 설계에 영향을 미친다. 예를 들어, 클라우드 벤더사의 가격이나 인수 합병 등의 외부 요인이 시스템 설계에 영향을 줄 수 있다. + +### 5. **프로세스, 팀, 운영 문제에 관한 지식** + +- 소프트웨어 개발의 프로세스, 팀 간 소통, QA 프로세스 등의 요소도 아키텍처 설계에 영향을 미친다. 애자일 성숙도가 부족한 조직에서는 애자일 기반의 아키텍처를 도입하는 데 어려움을 겪을 수 있다. + +### 6. **도메인/아키텍처 동형성** + +- 특정 아키텍처 스타일은 특정 문제 영역과 잘 맞을 수 있다. 예를 들어, 마이크로커널 아키텍처는 플러그인 기반의 커스터마이징이 필요한 시스템과 잘 맞고, 공간 기반 아키텍처는 대규모 연산 작업이 필요한 시스템에 적합합니다. 반면, 모놀리식 아키텍처는 확장성에 어려움이 있을 수 있다. + +### 7. **모놀리스 vs 분산 아키텍처** + +- 아키텍트는 아키텍처의 특성을 고려해 모놀리식 아키텍처가 적합한지, 아니면 분산 아키텍처가 필요한지를 결정해야 한다. 분산 아키텍처는 각 서비스별로 다른 아키텍처 특성을 필요로 할 수 있으며, 이로 인해 시스템 설계가 더욱 복잡해질 수 있다. + +### 8. **데이터 분할** + +- 아키텍트는 시스템 내에서 데이터를 어떻게 분할할 것인지, 각 서비스가 어떤 데이터를 저장할 것인지 결정해야 한다. 데이터 흐름을 잘 파악하고, 이를 최적화하는 설계를 해야 한다. + +### 9. **서비스 간 통신 방식** + +- 서비스 간 통신은 동기와 비동기 중 어느 방식을 선택할지 고민해야 한다. 동기 통신은 간편하지만 확장성에 한계가 있을 수 있고, 비동기 통신은 성능에서 장점이 있지만 구현과 디버깅이 복잡할 수 있다. 대부분의 경우 동기 통신을 기본으로 하고, 필요 시 비동기 통신을 사용하는 것이 좋다. + +### 10. **결과물과 아키텍처 기록** + +- 설계 과정이 완료되면, 아키텍트는 아키텍처 스타일과 하이브리드화가 반영된 아키텍처 토폴로지를 정의하고, 중요한 설계 원칙과 아키텍처 특성을 지키기 위한 아키텍처 피트니스 함수를 문서화해야 한다. + +## **18.3** 모놀리스 사례 연구: 실리콘 샌드위치 + +### **모놀리스 설계** + +- **장점**: 단순성, 빠른 개발과 배포, 관리 용이, 통합성. +- **단점**: 확장성 한계, 높은 커플링, 변화에 대한 유연성 부족. + +### **도메인/기술 분할 설계** + +- **장점**: 확장성, 독립적인 컴포넌트 관리, 기술 선택의 유연성. +- **단점**: 복잡성 증가, 서비스 간 통신 및 데이터 관리 어려움. + +### 18.3.2 마이크로커널 + +1. **맞춤성**: + - 실리콘 샌드위치에서 중요한 아키텍처 특성 중 하나는 맞춤성. + - 아키텍트는 도메인/아키텍처 동형성 검토 후 마이크로커널 아키텍처로 구현할 수 있다. +2. **마이크로커널 아키텍처**: + - 코어 시스템은 도메인 컴포넌트와 단일 관계형 데이터베이스로 구성된다. + - 커스터마이징은 플러그인 형태로 제공되며, 플러그인 간 커플링 없이 독립적으로 데이터를 유지한다. + - 향후 분산 아키텍처로의 마이그레이션 가능성을 염두에 두고 설계된다. +3. **백엔드 포 프런트엔드 (BFF) 패턴**: + - BFF 패턴을 활용하여 프런트엔드에 적합한 형태로 백엔드 데이터를 변환한다. + - 예시: iOS용 BFF가 데이터를 iOS 네이티브 애플리케이션의 사양에 맞게 변환한다. + - 이를 통해 마이크로커널 스타일의 유연한 사용자 인터페이스와 확장 지원을 제공한다. +4. **통신 방식**: + - 실리콘 샌드위치 아키텍처는 엄청난 성능이나 탄력성을 요구하지 않으며, 오래 걸릴 작업이 없으므로 동기식 통신으로 충분하다.