소프트웨어 아키텍처 101의 후속작으로 나중에 바꾸기 어려운 것 을 중점적으로 다룬다
저자: 대부분의 아키텍처에서 데이터는 모든것이다.
- 피트니스 함수: 아키텍처 특성이나 무결성을 객관적으로 평가하는 매커니즘
- 측정 가능한 값을 제공해야 한다
- 도메인 지식이 불필요한 함수
- archUnit, Jdepend 와 같은 라이브러리 존재
- 동기 vs 비동기 / 블록킹 vs 논 블록킹
- 동기/비동기: Caller 가 Callee의 응답의 기다려야 하는지 여부
- 블록킹/논 블록킹: Caller가 Callee에게 코드 실행 권리**(제어권)를 넘겨주는지 여부**
- 아키텍처 퀀텀
- 요소들이 통신하는 방법에 관한 토폴로지 및 동작을 나타냄
- 커플링: 한쪽을 변경하면 반대쪽도 변경해야 하는 경우
- 정적: 서비스가 어떻게 연결되는 지를 의미
- 데이터베이스는 정적 커플링을 판단하는 기준
- 한 개의 퀀텀은 단독 프로덕션처럼 실행 가능해야 한다
- 동적: 런타임에 서로를 어떻게 호출하는 지를 의미
- 분산 아키텍처에서 교차 트랜잭션을 최대한 하지 말아야 한다
- 높은 확장성/탄력성이 필요하다면 동기 통신을 자제해야 한다
- 아키텍처 모듈성 및 모놀리스 분해
- 마이크로 서비스에서 특정 순서를 지켜 세트로 배포해야 한다면 모놀리스로 다시 만들어야 한다
- 모놀리스 분해
- 분해 가능한 코드 베이스(컴포넌트) 인지 확인해야 하며 몇몇 메트릭을 이용하여 판단할 수 있다
- 구심 커플링: 다른 코드 아티팩트로 진입하는 접속 수
- 원심 커플링: 다른 코드 아티팩트에서 사용되는 수
- 추상도: 코드 베이스의 추상화 정도. 높을 수록 추상화가 강함
- 불안정도: 커플링이 높아서 깨지기 쉬운 정도. 높을 수록 안정적이나 재 사용이 어렵다
- 일반화 거리: 추상도와 불안정도 사이의 이상적인 관계. 0의 값에 가까울 수록 좋다
- 컴포넌트 기반 분해
- 컴포넌트: 시스템에서 역할 및 책임과 기능이 명확하게 정의된 구성 요소
- 간단하게 분해가 가능한 경우 사용됨
- 전술적 분기
- 팀에게 코드의 복사본을 부여한 후 각자 필요없는 코드를 삭제하면서 진행하는 방식
- 남은 코드는 리팩토링을 통해 컴포넌트를 견고히 한다
- 컴포넌트 기반 분해 패턴
- 컴포넌트 기반으로 모놀리식 어플리케이션을 분해하는 패턴과 적용 순서
-
- 컴포넌트 식별 및 사이징
- 컴포넌트의 사이즈를 적당한 크기로 조각내어 논리적으로 분해하는 작업
- 유용한 메트릭: 총 문장의 수(조건문 or 분기문 등등)
-
- 공통 도메인 컴포넌트 수집
- 공통 도메인 로직을 찾아 단일 컴포넌트로 만드는 과정
- 중복 기능을 제거하여 단일 기능으로 제공하기 위함
-
- 컴포넌트 눌러펴기
- 디렉토리 구조나 네임스페이스에서 **리프 노드(서브 패키지 구조 제거)**만 존재하도록 편다
- 루트 네임스페이스(서브 도메인) 재 구축: 하위 디렉토리/네임스페이스가 존재하는 컴포넌트
- 위 과정을 통해 제대로 된 네임스페이스를 구축하고 공유 코드 위치를 새로 결정한다
-
- 컴포넌트 디펜던시 결정
- 어플리케이션 분해 후 실제 컴포넌트 디펜던시 그래프가 어떨지 미리 확인하는 작업
- 너무 디펜던시가 크다면 새로 작성이 더 나을 수 있다
- 디펜던시에 따라 컴포넌트를 합칠지 분해할 지 가늠한다
-
- 컴포넌트 도메인 생성
- 컴포넌트를 논리적으로 그룹핑하는 단계
- 서브 도메인 이름에 따라 적절한 컴포넌트가 그룹핑되었는지 확인한다
-
- 도메인 서비스 생성
- 그룹핑된 도메인을 개별 서비스로 만들어서 구축하는 단계
- 인프라를 분해하는 작업은 이 작업이 잘 구축되었는지 확인 후에 작업한다 → 선 SOA 구축
- 운영 데이터 분리
- 분해인
- 어떤 경우 데이터베이스를 분해해야 하는지에 대한 지침
- 고려 요인
- 너무 많은 서비스가 변경의 영향을 받는 경우
- 커넥션이 너무 많이 발생하는 경우
- 내고장성이 필요한 서비스인 경우
- 데이터베이스 타입 최적화(다른 데이터베이스 사용) 이 필요한 경우
- 통합인
- 어떤 경우 데이터베이스를 합쳐야 하는지에 대한 지침
- 고려 요인
- ACID 단일 트랜잭션이 필요한 경우
- 밀접한 연관 관계(외래 키, 트리거, 뷰) 가 존재하는 경우
- 데이터 도메인 분해 프로세스
-
- 데이터베이스 분석과 도메인 생성
- 연관된 테이블을 그룹핑하여 데이터 도메인 후보를 추려낸다
-
- 데이터 도메인에 테이블을 할당
- 데이터 도메인마다 스키마를 생성한다
- 스키마에 도메인에 해당하는 테이블을 이동한다
- 다른 도메인의 연관성 및 커플링을 제거한다
-
- 데이터베이스 커넥션 분리
- 다른 도메인의 연결된 데이터베이스 커넥션을 통신으로 변경한다
-
- 개별 데이터 베이스 서버로 스키마 이전(데이터 마이그레이션)
-
- 이전한 데이터베이스 서버로 커넥션을 변경한다
- 데이터 베이스 종류 선택
- 관계형: ACID 성격의 트랜잭션이 필요할 때 선택
- key-value: 특정 키로만 조회하는 케이스가 많은 경우 선택
- 문서형: 애그리거트 지향인 시스템인 경우 선택
- 컬럼형: 희소데이터 처리 / 분석에 사용되는 경우 선택
- 그래프: 데이터간 연결성이 강한 경우 선택 → 방향 선택이 매우 중요
- NewSql: 가용성/내분할성이 필요하고 ACID가 필요한 경우 선택
- 시계열: 일정 시간 동안의 변경/ 추적이 필요한 경우 선택
- 서비스 세분도 결정
- 코드 재 사용 패턴
- 데이터 오너쉽
- 분산 트랜잭션 및 패턴
- 분산 워크 플로우 관리
- 트랜잭셔널 사가 종류
- 계약
- 분석 데이터의 관리