Building Evolutionary Architectures(진화적 아키텍처)

진화적 소프트웨어 아키텍처는 여러 차원에 걸쳐 유도된 변화guided change와 점진적 변화incremental change를 지원한다.

1장, 한빛미디어 공식 미리보기 p.29

한 번 잘 그린 아키텍처가 시간이 지나면서 왜 무너지는지, 무너지지 않게 하려면 무엇을 기계로 붙잡아야 하는지를 다루는 책이다. 저자들이 내놓은 답이 피트니스 함수다. 지키고 싶은 아키텍처 특성을 사람이 문서로 적어 두는 대신 실행 가능한 검사로 적어 두고, 배포 파이프라인이 매번 돌린다.

이 페이지는 한빛미디어 번역본의 장 구성을 따라 정리했다. 용어는 번역본 표기를 쓴다. connascence를 이 번역본은 동조성이라 옮겼고, expand/contract는 확장/수축 패턴이다.

장·절·소절 제목은 한빛 공식 미리보기의 3단계 목차와 원서 목차를 대조해 확인한 것이고, 절 안의 내용은 공개 자료로 확인되는 범위까지만 적었다. 확인 범위는 아래에 장별로 남겨 뒀다.

서지

항목 내용
제목 진화적 아키텍처: 피트니스 함수, 거버넌스 자동화를 활용해 생산성 높은 소프트웨어 구축하기
원서 Building Evolutionary Architectures: Automated Software Governance (O'Reilly, 2판, 2022)
저자 닐 포드(Neal Ford), 레베카 파슨스(Rebecca Parsons), 패트릭 쿠아(Patrick Kua), 프라모드 사달게이(Pramod Sadalage)
역자 정병열
출판사 한빛미디어
출간 2023년 8월 31일
분량 304쪽
ISBN 9791169211345

저자 넷은 모두 쏘우트웍스(Thoughtworks) 소속이거나 출신이다. 레베카 파슨스는 CTO이고 유전 알고리즘을 비롯한 진화적 컴퓨팅을 오래 연구했다. 피트니스 함수라는 이름이 어디서 왔는지가 여기서 설명된다.

프라모드 사달게이는 데이터 및 데브옵스 책임자로, 2000년대 초반에 버전 관리되는 스키마 마이그레이션을 기반으로 관계형 데이터베이스를 진화적으로 설계하는 방식을 만든 사람이다. 2판에서 정식 공저자로 합류했다.

1판과 2판의 차이

원서 1판은 2017년에 나왔고 부제가 Support Constant Change였다. 2판은 부제가 Automated Software Governance로 바뀌었다. 제목이 아니라 부제가 바뀐 자리에 이 개정의 요지가 있다.

저자들이 「이 책에 대하여」에서 밝힌 개정 이유는 이렇다.

개정판은 초판의 구조를 일부 변경했다. 진화적 소프트웨어 시스템의 엔지니어링 관행, 구축 편의성을 높이는 구조적 접근이라는 두 가지 주제를 이전보다 명확하게 설명하기 위해서다.

한빛미디어 공식 미리보기

팟캐스트에서는 더 구체적으로 말한다.

  • 아키텍처 특성을 지키는 일과 보안·지표·코드 품질 같은 전통적 거버넌스가 사실상 같은 일이라는 것을 알게 됐다. 그래서 거버넌스를 자동화하는 4장을 새로 넣었다. 목표는 사람의 판단을 없애는 데 있지 않다. 객관적으로 잴 수 있는 것은 기계에 넘기고, 사람은 진짜 트레이드오프에만 붙는다. 저자들은 기존의 거버넌스를 "체크박스 채우는 활동"이라 부른다.
  • 1판은 아키텍처 스타일들을 점수표로 비교했는데, 2판에서는 진화 가능성을 결국 커플링이 좌우한다고 보고 구조를 다루는 2부를 따로 두었다. 5장이 여기서 신설됐다.
  • 프라모드 사달게이가 합류하면서 데이터 장을 넓혔다. 데이터가 지금 소프트웨어 아키텍처에서 훨씬 더 광범위해졌기 때문이라고 밝히고 있다.

책의 구성

무엇을 다루나
1부 역학 1~4장 진화의 목표를 구현할 메커니즘과 엔지니어링 관행. 기술, 도구, 범주
2부 구조 5~6장 진화와 거버넌스의 효과를 높이는 설계 결정. 커플링, 재사용, 아키텍처 스타일, 데이터
3부 영향력 7~9장 실제로 세우고 옮기는 방법, 빠지기 쉬운 함정, 조직과 프로세스에 들이는 방법

이 페이지의 확인 범위

절·소절 제목 절 안의 내용
1장 3단계 전부 확인 번역본 본문 일부를 미리보기로 직접 확인. 이 페이지에서 근거가 가장 두꺼운 장
2장 3단계 전부 확인 분류축 여섯의 이름과 값은 목차로 확실. 각 축의 서술은 공개 스터디 정리로 보완
3장 3단계 전부 확인 절이 하나뿐인 짧은 장. 공개 스터디 정리의 인용으로 보완
4장 3단계 전부 확인 2판 신설. 항목과 도구 이름은 확실. 각 항목의 서술 내용은 확인 못 한 부분이 있다
5장 3단계 전부 확인 2판 신설. 동조성·퀀텀·계약의 뼈대는 공개 스터디 정리의 인용으로 확인
6장 3단계 전부 확인 확장/수축 패턴은 인용으로 확인. 절차의 구체 서술은 확인 못 함
7장 3단계 전부 확인 원리 다섯과 가이드라인 여덟은 확실. 사례 내용은 일부만
8장 3단계 전부 확인 함정·안티패턴 이름과 분류가 목차에 그대로 있어 가장 확실한 장
9장 3단계 전부 확인 항목은 확실. 사례연구 내용은 대부분 확인 못 함

한빛 공식 미리보기에 3단계 목차 전체가 실려 있어서 9장 전부의 소절 제목까지 확보했다. 다만 절 안의 서술을 공개 자료로 채운 정도는 장마다 다르다. 확인하지 못한 자리는 본문에 그대로 적어 두고 빈 채로 두었다.


CHAPTER 1 진화적 소프트웨어 아키텍처

다루는 것

소프트웨어는 배포된 순간부터 주변이 변한다. 프레임워크가 올라가고, 운영 환경이 바뀌고, 규제가 생기고, 트래픽 모양이 달라진다. 처음 설계가 지키려던 성질은 아무도 건드리지 않아도 시간이 지나면 조용히 무너진다.

이 현상을 부르는 이름이 비트 부패이고 소프트웨어 엔트로피다.

저자들은 소프트웨어 품질을 유지하기 어려운 이유를 둘로 본다. 하나는 복잡하게 얽힌 작동부 전체를 사람이 관리할 수 없다는 것이고, 다른 하나는 개발 생태계가 동적 균형 상태라는 점이다.

외발자전거를 탄 사람에 비유한다. 가만히 서 있는 것처럼 보여도 실제로는 계속 움직이고 있다.

진화 가능한 소프트웨어의 근본 원리는 둘로 정리된다.

하나는 애자일 소프트웨어 운동에서 확립된 효과적인 엔지니어링 관행이며 다른 하나는 변화와 거버넌스를 촉진하는 아키텍처 구조다.

한빛미디어 공식 미리보기

이 둘이 그대로 2판의 1부와 2부다.

1.1절은 진화적 소프트웨어의 과제를 세우고, 1.2절이 정의를 내린다. 정의는 세 조각으로 쪼개져 각각 소절이 된다.

  • 유도된 변화(1.2.1): 아무 방향으로나 변하지 않는다. 무엇을 지킬지 먼저 정하고 그 기준이 변화를 유도한다. 그 기준이 피트니스 함수다.
  • 점진적 변화(1.2.2): 작은 단위로 바꾸고 작은 단위로 배포한다. 한 번에 크게 바꾸는 방식은 되돌리기 어렵고 무엇이 깨졌는지도 알기 어렵다.
  • 다중 아키텍처 차원(1.2.3): 여기서 진화하는 대상은 기술 구조만이 아니다. 기술, 데이터, 보안, 운영 네 차원을 든다. 하나만 붙잡으면 나머지가 그 뒤에서 무너진다.

1.3절과 1.4절은 질문 두 개를 받아 답한다. 모든 것이 늘 변하는데 장기 계획이 어떻게 가능한가, 아키텍처를 한 번 세운 다음 시간에 따른 성능 저하를 어떻게 막는가. 원서에서는 절 제목 자체가 이 두 문장의 물음표 형태였고, 번역본은 「상시 변화하는 환경의 장기 계획 수립 가능성」·「시간에 따른 아키텍처의 성능 저하 방지」라는 명사구로 옮겼다.

1.5절 「왜 진화인가?」는 하필 진화라는 단어를 고른 이유를 설명하는 자리다. 여러 공개 정리에서 이 절이 적응과 진화를 갈라 놓는다고 전하는데, 적응이 우아함이나 수명과 무관하게 그저 돌아가게 만드는 쪽이라면 진화는 변하는 환경에서 목적에 부합한 채로 살아남는 쪽이라는 구분이다. 다만 이 서술은 미리보기 본문에서 직접 확인하지 못했다.

피트니스 함수도 1장에서 먼저 언급된다.

피트니스 함수란 예상 설계 솔루션의 설정 목표 달성도를 간단하게 확인할 수 있는 목적 함수다.

한빛미디어 공식 미리보기 p.30

새로 나오는 이름

  • 비트 부패, 소프트웨어 엔트로피
  • 유도된 변화, 점진적 변화, 다중 아키텍처 차원
  • 아키텍처 차원 넷: 기술, 데이터, 보안, 운영
  • 아키텍처 특성. 비기능적 요구사항, 시스템 품질 속성 같은 이름으로도 불린다
  • 진화성. 시스템이 진화하면서 나머지 특성을 보호한다는 뜻으로 쓴다
  • PenultimateWidgets. 책 전체의 사례연구를 맡는 가상 기업이다

본문 옆 박스로 「2000년에 마이크로서비스가 없었던 이유」와 「애자일 프로젝트에 아키텍처가 필요한가?」가 붙는다.


CHAPTER 2 피트니스 함수

다루는 것

이 책의 중심 장치다. 단위 테스트가 도메인 로직을 지키듯, 피트니스 함수는 아키텍처 특성을 지킨다. 이 대비가 장 전체를 관통한다.

이름은 유전 알고리즘에서 왔다. 해가 목표에 얼마나 가까운지 재는 함수를, 아키텍처가 목표에 얼마나 가까운지 재는 데 그대로 가져온 것이다.

피트니스 함수는 객관적으로 잴 수 있어야 한다. 유지보수성이 좋아야 한다는 문장은 검사할 수 없고, 순환 복잡도가 5 이하여야 한다는 문장은 검사할 수 있다.

저자들은 결과로 적고 방법은 팀에 맡기라고 말한다. 무엇이 중요한지는 알려 주되 어떻게 달성할지는 각 팀의 맥락에 맡긴다는 뜻이다. 마지막 절 「결과 vs 구현」이 이 이야기다.

구현 수단은 하나가 아니다. 모니터, 코드 메트릭, 카오스 엔지니어링, 아키텍처 테스트 프레임워크, 보안 스캐닝이 전부 피트니스 함수가 될 수 있다. 저자들이 한 일은 새 도구를 발명한 것이 아니라, 이미 흩어져 쓰이던 것들을 하나의 이름 아래 묶어 아키텍처 거버넌스의 수단으로 세운 것이다.

분류축 여섯

2.2절은 분류를 축 이름과 함께 정리한다. 소절 제목이 그대로 축이다.

소절 무엇을 가르나
2.2.1 스코프 원자 vs 전체 단일 콘텍스트에서 한 측면만 보는가, 공유 콘텍스트에서 여러 측면을 조합해 보는가
2.2.2 케이던스 트리거 vs 지속 vs 시간 커밋·배포 같은 사건에 반응해 도는가, 계속 도는가, 정해진 시점마다 도는가
2.2.4 결과 정적 vs 동적 통과 기준이 고정인가, 상황에 따라 허용 범위가 움직이는가
2.2.5 호출 자동 vs 수동 파이프라인이 돌리는가, 사람이 돌리는가
2.2.6 선제적 의도 vs 긴급 미리 정해 둔 것인가, 문제가 터진 뒤에 붙인 것인가
2.2.7 커버리지 도메인별 특정 도메인에만 해당하는 검사를 따로 둘 것인가

2.2.3은 트리거와 지속 중 무엇을 고를지를 다루는 사례연구다.

축을 나누는 이유는 분류 자체가 목적이어서가 아니다. 어떤 검사를 언제 어디서 돌릴지를 정하려면 이 축들이 필요하다. 원자적이고 빠른 피트니스 함수는 파이프라인 앞쪽에, 전체적이고 느린 것은 뒤쪽에 놓는 식이다.

시스템 피트니스 함수

개별 피트니스 함수들을 한데 모은 개념이다. 특성끼리 충돌할 때 쓰는 언어가 된다. 캐시를 넣으면 확장성은 오르지만 데이터 신선도가 떨어지는 식으로 두 특성이 부딪칠 때, 어느 쪽을 얼마나 내줄지 이야기할 자리를 만들어 준다.

그 밖의 절

  • 2.3 누가 작성하는가: 아키텍트 혼자 쓰는 것이 아니다.
  • 2.4 테스트 프레임워크 선택: 피트니스 함수 전용 프레임워크가 따로 있는 것이 아니라, 이미 쓰는 테스트·지표 도구를 그 용도로 쓴다.

피트니스 함수도 코드베이스의 일부다. 아키텍처 요구사항이 바뀌면 피트니스 함수도 따라 바뀌어야 한다.

새로 나오는 이름

  • 피트니스 함수, 시스템 피트니스 함수
  • 스코프·케이던스·결과·호출·선제적·커버리지 여섯 축
  • 원자 vs 전체, 트리거 vs 지속 vs 시간, 정적 vs 동적, 자동 vs 수동, 의도 vs 긴급

확인 못 한 것

피트니스 함수의 우선순위를 핵심·관련·무관 세 등급으로 나눈다는 서술이 여러 영어권 공개 노트에 나오는데, 대부분 1판 기준이고 2판 본문 어디에 해당하는지는 확인하지 못했다.


CHAPTER 3 점진적 변화 엔지니어링

다루는 것

절이 하나뿐인 짧은 장이다. 피트니스 함수를 정의했으니 이제 그것을 계속 돌리는 장치를 세운다.

점진적 변화를 개발자 관점과 운영자 관점 두 갈래로 나눠 논의하고, 배포 파이프라인을 피트니스 함수가 실행되는 자리로 놓는다. 절 아래 소절이 배포 파이프라인 하나와 사례연구 둘뿐이라는 구성 자체가 그 배치를 보여 준다.

저자들은 지속적 통합 서버와 배포 파이프라인을 구분하는데, 통합 서버는 빌드와 테스트가 끝나는 곳이고, 파이프라인은 커밋에서 프로덕션까지 이어지는 여러 단계다. 피트니스 함수는 이 단계들에 배치된다.

배치 순서는 비용과 범위를 따른다. 싸고 빠르고 원자적인 것이 앞, 비싸고 느리고 전체적인 것이 뒤다. 단계를 병렬로 펼쳤다가 전부 통과해야 다음으로 넘기는 팬아웃·팬인 구성도 여기서 나온다.

이 장에는 전제가 하나 깔려 있다. 점진적 변화는 개발팀의 엔지니어링 성숙도를 요구한다는 것이다. 파이프라인이 없으면 피트니스 함수를 자주 돌릴 수 없고, 자주 돌지 않는 피트니스 함수는 늦게 알려 준다.

사례연구가 둘 붙는다. PenultimateWidgets에 피트니스 함수를 추가하는 사례(3.1.2)와, 자동화 빌드에서 API 일관성을 검증하는 사례(3.1.3)다. 뒤쪽은 openapi.yaml을 기준으로 검증 체인을 거는 방식이다.

새로 나오는 이름

  • 배포 파이프라인. 지속적 통합 서버와 구분된다
  • 팬아웃·팬인
  • 기능 토글

CHAPTER 4 아키텍처 거버넌스 자동화

2판에서 새로 들어간 장이고, 부제가 바뀐 이유가 여기 있다.

다루는 것

거버넌스라는 말은 보통 문서와 회의를 떠올리게 한다. 저자들의 진단은 이렇다. 아키텍트가 위키에 원칙을 적어 두지만 제대로 읽는 사람은 거의 없고, 실행이 뒤따르지 않는 원칙은 일정 압박과 제약 앞에서 유명무실해진다.

그래서 원칙을 피트니스 함수로 바꾸면 생략하거나 건너뛰지 못하게 절차가 보장한다.

장의 서술은 고도를 계단식으로 올려, 코드 수준에서 시작해 통합 아키텍처, 데브옵스, 엔터프라이즈 아키텍처로 올라간다.

코드 기반 피트니스 함수 (4.2)

코드에서 잴 수 있는 것들이다.

소절 항목 무엇을 재나
4.2.1 구심 및 원심 커플링 구심은 이 모듈로 들어오는 연결 수, 원심은 나가는 연결 수
4.2.2 추상도, 불안정도, 메인 시퀀스와의 거리 불안정도는 구심과 원심의 합에 대한 원심의 비율이다. 추상도와 불안정도가 균형을 이루는 선이 메인 시퀀스이고, 거기서 얼마나 떨어졌는지를 잰다
4.2.3 임포트 방향성 어느 패키지가 어느 패키지를 가져다 쓰는가. 계층 규칙 위반이 여기서 드러난다
4.2.4 순환 복잡도와 '군집' 거버넌스 분기 복잡도를 잰다

턴키 도구 (4.3)

이미 나와 있어서 가져다 쓰면 되는 것들이다.

  • 오픈 소스 라이브러리의 적법성(4.3.1): 라이선스 검사를 파이프라인에 건다
  • 접근성 및 기타 아키텍처 특성(4.3.2): 도구가 이미 지원하는 특성들
  • ArchUnit(4.3.3): 별도 소절로 다뤄진다. 패키지 종속성, 클래스 의존성, 상속, 애너테이션, 계층 다섯 종류의 검사가 붙는다. 아키텍처 규칙을 테스트 코드로 적어 두고 빌드에서 깨뜨리는 방식이다
  • 코드 거버넌스와 린터(4.3.4)
  • 이미 사용 중인 피트니스 함수(4.3.8): 새로 도입할 필요 없이, 지금 쓰는 도구 중 상당수가 이미 피트니스 함수라는 이야기다

사례연구 셋이 붙는다. 가용성 피트니스 함수, 카나리아 릴리스와 부하 테스트, 이식 원칙이다.

위로 올라가면

  • 통합 아키텍처(4.4): 마이크로서비스의 통신 거버넌스를 다룬다. 서비스 사이의 호출을 어떻게 통제할 것인가. 피트니스 함수 구현 방법을 고르는 사례연구가 붙는다
  • 데브옵스(4.5): 배포·운영 쪽에서 거는 검사
  • 엔터프라이즈 아키텍처(4.6): 조직 전체에 걸치는 검사. 하루 60회 배포하면서 아키텍처를 재구성한 사례연구가 실리고, 정확성 피트니스 함수라는 개념이 나온다

저자가 제시하는 기준

마지막 두 절이 이 장의 태도를 정한다.

  • 피트니스 함수는 무기가 아닌 체크리스트다(4.7). 자동화된 거버넌스를 팀을 때리는 도구로 쓰면 안 된다. 피트니스 함수가 붙는 이유는 통제가 아니라, 사람이 매번 확인해야 하는 짐을 덜기 위해서다.
  • 피트니스 함수 문서화(4.8). 왜 이 검사가 있는지 남기지 않으면, 나중에 아무도 이유를 모른 채 통과시키려고만 하게 된다.

새로 나오는 이름

  • 구심 커플링, 원심 커플링, 추상도, 불안정도, 메인 시퀀스와의 거리
  • 임포트 방향성, 순환 복잡도와 '군집' 거버넌스
  • ArchUnit, 린터, 정확성 피트니스 함수
  • 피트니스 함수 로드맵

확인 못 한 것

각 소절이 실제로 어떤 예제 코드와 어떤 서술로 채워져 있는지는 대부분 확인하지 못했다. 위 내용은 목차 항목과 공개 스터디 정리에서 확인되는 범위까지다.


CHAPTER 5 진화하는 아키텍처 토폴로지

2판에서 새로 들어간 장이다. 진화 가능성을 커플링이 좌우한다는 판단이 여기 담긴다.

다루는 것

무엇이 아키텍처를 못 바꾸게 만드는가. 답은 커플링이다. 그래서 커플링을 말하는 어휘부터 세운다.

동조성(5.1.1). 한 컴포넌트를 바꿨을 때 시스템의 정확성을 유지하려면 다른 컴포넌트도 고쳐야 한다면, 두 컴포넌트는 동조적이다. 멜리어 페이지존스가 만든 용어이고, 커플링을 있다·없다가 아니라 강도의 등급으로 말하게 해 준다.

저자들의 표현으로는 커플링을 세련되게 묘사한 언어일 뿐이지만, 개발자에게 커플링 개념을 설명하기에는 더 좋은 언어다.

동조성은 정적과 동적으로 나뉜다.

갈래 유형 언제 드러나나
정적 동조성 명칭, 타입, 의미, 위치, 알고리즘 코드를 읽어서 알 수 있다
동적 동조성 실행, 시점, 값, 식별 실행해 봐야 알 수 있다

그리고 동조성에는 세 속성이 붙는다. 강도, 지역성, 정도다. 같은 종류의 동조성이라도 가까이 있으면 덜 위험하고 멀리 퍼져 있으면 더 위험하다는 이야기다.

5.1.2절은 도메인 주도 설계의 경계 콘텍스트가 동조성과 어디서 겹치는지를 다룬다.

아키텍처 퀀텀 (5.2)

아키텍처 퀀텀이란 높은 기능 응집도를 갖추었으며 독립적으로 배포 가능한 컴포넌트를 가리킨다. 시스템이 제대로 작동하기 위해 필요한 모든 구조적 요소가 아키텍처 퀀텀에 속한다.

prostars.net 서평에 인용된 본문

세 조건이 소절 제목으로 그대로 나온다.

  • 독립 배포(5.2.1): 다른 것을 함께 배포하지 않고 이것만 올릴 수 있는가
  • 고기능 응집도(5.2.2): 하나의 목적을 위해 모인 것들인가
  • 강한 정적 커플링(5.2.3): 퀀텀 경계 안쪽이 단단한가. 정적 커플링은 데이터베이스까지 포함하므로, 단일 데이터베이스에 의존하는 시스템은 퀀텀을 하나 이상 가질 수 없다

여기에 동적 퀀텀 커플링(5.2.4)이 붙는다. 런타임에 퀀텀끼리 어떻게 얽히는지를 통신·일관성·조정 세 축으로 본다. 실행 중에 강하게 얽히면 배포만 따로 되고 실제로는 하나처럼 움직인다.

계약 (5.3)

계약의 엄격도가 퀀텀 사이의 커플링을 정한다. 엄격한 쪽에 XML·JSON 스키마와 객체, RPC가 있고, 느슨한 쪽에 값 기반 JSON과 맵이 있다. GraphQL과 REST가 중간이다.

엄격한 계약은 어긋남을 빨리 잡아 주지만 양쪽을 같이 바꿔야 하고, 느슨한 계약은 따로 움직이게 해 주지만 어긋남이 늦게 드러난다. 저자들의 처방은 필요한 것만 아는 수준으로 계약을 유지하라는 것이다. 필요 이상으로 많은 데이터를 계약에 실어 보내는 스탬프 커플링이 안티패턴으로 나온다.

진화적 마이크로서비스 아키텍처를 다룬 사례연구가 붙는다.

재사용 패턴 (5.4)

재사용을 두고 내린 판단이 소절 제목에 그대로 들어 있다. 효과적인 재사용은 추상화와 낮은 변동성의 조합이다.

자주 바뀌는 것을 재사용 단위로 만들면 그 재사용이 곧 커플링이 된다. 이 판단은 8장의 컴포넌트 재사용 사례와 이어진다.

재사용을 커플링 없이 하는 두 가지 방식이 이어서 나온다.

  • 사이드카 및 서비스 메시(5.4.2): 로깅·인증·추적 같은 운영 관심사를 도메인 코드와 직교하게 붙인다
  • 데이터 메시(5.4.3): 데이터를 도메인 팀이 제품으로 소유하되 그 소유가 직교하게 붙도록 한다. 데이터 제품 퀀텀이라는 개념이 나오고, 원천·집계·목적 세 종류로 나뉜다

새로 나오는 이름

  • 동조성. 정적(명칭·타입·의미·위치·알고리즘)과 동적(실행·시점·값·식별), 그리고 강도·지역성·정도
  • 아키텍처 퀀텀, 동적 퀀텀 커플링(통신·일관성·조정)
  • 스탬프 커플링
  • 직교 커플링, 사이드카, 서비스 메시, 데이터 메시, 데이터 제품 퀀텀

CHAPTER 6 진화적 데이터

다루는 것

코드는 바꾸기 쉬워도 데이터는 아니다. 스키마를 바꾸면 이미 쌓인 데이터가 있고, 그 데이터를 보는 다른 시스템이 있다. 사달게이가 공저자로 합류하면서 넓어진 장이다.

진화적 데이터베이스 설계 (6.1)

진화적 스키마(6.1.1)는 세 가지를 요구한다. 테스트할 수 있어야 하고, 버전이 관리되어야 하고, 증분으로 변경되어야 한다. 스키마 변경을 소스코드와 같은 방식으로 다루자는 이야기다.

마이그레이션 도구는 배포 라인에서 증분 변경을 자동 수행하는 유틸리티로 다뤄지고, 한번 적용된 마이그레이션은 되돌릴 수 없다고 간주한다.

공유 데이터베이스 통합(6.1.2)은 여러 서비스가 한 데이터베이스를 함께 쓰는 상태를 푸는 이야기다. 여기서 확장/수축 패턴이 나온다.

커플링을 해소하는 일반적인 리팩터링 패턴이 바로 확장/수축 패턴이다.

공개 스터디 정리에 인용된 본문 (Yoon-Hong-Chan, junho3)

시작 상태와 종료 상태 사이에 이전 상태와 변경 상태가 동시에 존재하는 구간을 만들어 두는 방식이다. 그 구간 동안에는 어느 소비자도 깨지지 않는다.

상황을 셋으로 나눠 다룬다.

  • 통합 지점도 없고 레거시 데이터도 없는 경우
  • 레거시 데이터는 있지만 통합 지점은 없는 경우
  • 기존 데이터와 통합 지점이 둘 다 있는 경우

세 번째가 실무에서 가장 흔하고 가장 어렵다.

부적절한 데이터 얽힘 (6.2)

데이터가 아키텍처를 묶어 버리는 자리들이다.

  • 2단계 커밋 트랜잭션(6.2.1): 여러 서비스에 걸친 트랜잭션은 그 서비스들을 사실상 하나의 퀀텀으로 묶는다. 저자들은 데이터베이스 트랜잭션이 강한 핵력처럼 아키텍처 퀀텀을 묶는다고 표현한다. 따로 배포되더라도 함께 움직여야 하는 상태가 된다
  • 데이터의 연식과 품질(6.2.2): 오래된 데이터에는 지금은 없어진 업무 규칙이 형태로 남아 있다. 비어 있는 컬럼, 일관성 없는 형식, 아무도 설명하지 못하는 플래그 같은 것들이다. 정리하지 않은 채로 서비스를 쪼개면 쪼갠 쪽으로 그대로 따라온다

PenultimateWidgets의 라우팅을 진화시키는 사례연구가 붙는다.

네이티브에서 피트니스 함수로 (6.3)

데이터베이스가 기본으로 제공하던 기능에 기대던 것을, 아키텍처가 쪼개진 뒤에는 피트니스 함수로 대신 지키는 이야기다.

  • 참조 무결성(6.3.1): 외래 키로 지키던 것을 경계가 갈라진 뒤에는 무엇으로 지킬 것인가
  • 데이터 중복(6.3.2): 테이블 공유, 서비스 간 통신, 인프로세스 캐싱 같은 선택지를 놓고 본다
  • 트리거 및 저장 프로시저 대체(6.3.3): 데이터베이스 안에 있던 로직을 밖으로 꺼낸다

관계형에서 비관계형으로 옮기는 사례연구가 붙는다.

새로 나오는 이름

  • 진화적 스키마, 데이터베이스 마이그레이션 도구
  • 공유 데이터베이스 통합, 확장/수축 패턴
  • 부적절한 데이터 얽힘, 데이터의 연식과 품질

CHAPTER 7 진화 가능한 아키텍처 구축

다루는 것

앞의 장들이 무엇을 왜 하는지였다면, 이 장은 어떻게 하는지다.

원리 다섯 (7.1)

소절 원리
7.1.1 책임이 따르는 마지막 순간 결정을 미룰 수 있는 마지막 순간까지 미룬다. 일찍 정하면 정보가 적은 상태로 정하게 된다
7.1.2 진화성을 높이는 설계 및 개발 진화성은 저절로 생기지 않는다. 목표로 두어야 생긴다
7.1.3 포스텔의 법칙 보낼 때는 엄격하게, 받을 때는 관대하게. 계약이 조금 달라져도 견디게 만든다
7.1.4 테스트성과 아키텍트 검사할 수 없는 것은 피트니스 함수로 만들 수 없다. 단일 책임을 지키는 구조가 테스트하기 쉽다
7.1.5 콘웨이의 법칙 시스템 구조는 그것을 만든 조직의 소통 구조를 닮는다

역학 (7.2)

세 단계다.

  1. 진화의 영향을 받는 차원을 식별한다
  2. 각 차원의 피트니스 함수를 정의한다
  3. 배포 파이프라인으로 피트니스 함수를 자동화한다

세 가지 상황 (7.3~7.5)

  • 그린필드 프로젝트(7.3): 처음부터 세우는 경우
  • 기존 아키텍처 개조(7.4): 커플링과 응집도를 적절하게 만드는 일이 중심이고, 상용 소프트웨어를 쓰고 있을 때의 제약을 따로 다룬다. 상용 패키지가 진화를 받쳐 주지 못하는 이유를 셋으로 정리한다
  • 아키텍처 마이그레이션(7.5): 마이그레이션 단계와, 모듈 상호작용을 어떻게 함께 진화시킬지를 다룬다. 무엇을 기준으로 쪼갤지는 비즈니스 기능 그룹, 트랜잭션 경계, 배포 목표 셋을 든다

가이드라인 여덟 (7.6)

이 장에서 가장 실용적인 절이다.

  • 불필요한 변동성 제거(7.6.1): 서버마다 조금씩 다른 상태를 없앤다. 눈송이 서버와 불변 인프라의 대비가 여기 나온다
  • 결정과 번복(7.6.2): 블루-그린 배포, 기능 토글처럼 되돌릴 길을 만들어 둔다
  • 예측성과 진화성(7.6.3): 앞으로 무엇이 필요할지 맞히려 하기보다, 무엇이 오든 바꿀 수 있게 만든다
  • 손상방지 계층 구축(7.6.4): 외부 의존을 내부 인터페이스 뒤에 둔다. 바깥이 바뀌어도 그 계층만 고치면 된다
  • 희생적 아키텍처 구축(7.6.5): 성공적으로 개념을 입증한 다음 버려지도록 설계된 아키텍처다. 버릴 것을 알고 짓는다
  • 외부 변화 경감(7.6.6): 서드파티가 내 핵심 의존성을 마음대로 바꾸도록 두면 안 된다는 이야기다. 「인터넷을 무너뜨린 11줄의 코드」라는 박스가 붙는다
  • 라이브러리 vs 프레임워크(7.6.7): 라이브러리는 내가 부르는 것이라 내가 원할 때 올리면 되고(풀), 프레임워크는 나를 부르는 것이라 그쪽 일정에 끌려간다(푸시). 프레임워크의 메이저 업데이트를 두 번 이상 미루면 대가를 치른다고 못박는다
  • 서비스 버전 내재화(7.6.8): 여러 버전을 서비스 안쪽에 감춘다

7.6의 마지막 소절인 7.6.9는 PenultimateWidgets 별점 서비스를 진화시키는 사례연구다.

피트니스 함수 주도 아키텍처 (7.7)

피트니스 함수가 설계를 거꾸로 이끄는 경우다. LMAX 팀 사례가 실린다. 성능이라는 하나의 목표를 극단까지 밀어붙인 결과로 디스럽터 패턴이 나온 이야기다.

새로 나오는 이름

  • 책임이 따르는 마지막 순간, 포스텔의 법칙, 콘웨이의 법칙
  • 눈송이 서버, 불변 인프라, 블루-그린 배포
  • 손상방지 계층, 희생적 아키텍처
  • 풀과 푸시, 서비스 버전 내재화
  • 피트니스 함수 주도 아키텍처, 디스럽터

CHAPTER 8 진화적 아키텍처의 함정과 안티패턴

다루는 것

목차 자체가 목록이라 이 책에서 가장 확실하게 옮길 수 있는 장이다.

저자들은 안티패턴과 함정을 구분한다. 안티패턴은 처음에는 괜찮아 보였다가 나중에 가서야 실수였음이 드러나는 것이고, 함정은 표면적으로 좋은 아이디어처럼 보였다가 곧바로 나쁜 본색을 드러내는 것이다. 소절 제목에 유형이 붙어 있어서 어느 쪽인지 바로 알 수 있다.

기술 아키텍처 (8.1)

소절 유형 이름 무엇이 문제인가
8.1.1 안티패턴 마지막 10%의 덫, 로우코드/노코드 90%는 빠르고 우아하게 되는데 남은 10%가 안 된다. 그 10%가 결국 이 시스템을 이 시스템이게 만드는 부분이다
8.1.3 안티패턴 벤더 킹 특정 벤더를 중심으로 아키텍처를 세운다. 조직과 도구가 병적인 수준의 커플링을 이룬다. 외부 소프트웨어는 통합 지점으로 다루라는 것이 처방이다
8.1.4 함정 유출된 추상화 모든 비자명한 추상화는 언젠가 샌다. 아래층을 전혀 모른 채 위층만 다룰 수 있는 상태는 오지 않는다
8.1.5 함정 이력서 주도 개발 문제에 맞아서가 아니라 써 보고 싶어서 고른다

8.1.2는 PenultimateWidgets의 컴포넌트 재사용 사례연구다.

증분 변경 (8.2)

소절 유형 이름 무엇이 문제인가
8.2.1 안티패턴 부적절한 거버넌스 조직 전체에 하나의 기술 표준을 강제한다. 단순한 서비스도 복잡한 표준을 지고 간다. 반대 방향으로 지나치게 밀어붙인 강제 디커플링도 여기서 다룬다
8.2.3 함정 릴리스 속도 저하 배포가 느리면 피트니스 함수가 자주 못 돈다. 검사가 있어도 늦게 알게 된다. 리드 타임과 순환 주기를 구분해서 본다

8.2.2는 PenultimateWidgets의 'Just Enough' 거버넌스 사례연구다. 하나의 표준을 강제하는 대신 소형·중형·대형 세 등급의 기술 스택을 두고 팀이 자기 서비스의 복잡도에 맞는 등급을 고르게 하는 방식이다.

비즈니스 관심사 (8.3)

소절 유형 이름 무엇이 문제인가
8.3.1 함정 제품 맞춤화 고객마다 다르게 만들어 주다 보면 테스트해야 할 조합이 곱으로 늘어난다
8.3.2 안티패턴 기록 시스템에 기반한 보고 시스템 운영 데이터베이스에 직접 분석 질의를 건다. 보고가 스키마를 붙잡아 운영 쪽 변경을 막는다
8.3.3 함정 과도하게 긴 계획 기간 오래 계획할수록 이미 들인 것이 아까워진다. 매몰 비용이 판단을 붙잡는다

CHAPTER 9 아키텍처 실천

다루는 것

기술이 아니라 조직과 돈 이야기다. 앞의 것들을 실제 회사에 어떻게 들이는가.

조직적 요인 (9.1)

첫 소절이 콘웨이의 법칙이다. 조직 구조를 그대로 둔 채 시스템 구조만 바꾸려 하면 안 된다. 하위 항목으로 교차기능팀을 기본으로 둘 것, 비즈니스 기능 중심으로 팀을 조직할 것, 인지 부하와 비즈니스 기능의 균형을 맞출 것, 프로젝트가 아니라 제품으로 생각할 것, 팀이 지나치게 커지지 않게 할 것, 팀 커플링 특성을 볼 것이 붙는다.

문제는 사람의 수가 아니라 사람들이 만들어 내는 연결의 수라는 지적이다. 팀 토폴로지의 네 패턴(스트림 정렬팀, 활성화 팀, 난해한 하위시스템 팀, 플랫폼 팀)도 여기서 참조된다.

이어서 문화(9.1.2)와 실험 문화(9.1.3)를 다룬다. 실험을 장려하는 방법을 여섯 가지 든다. 외부 아이디어 도입, 명시적 개선 장려, 스파이크 구현과 안정화, 혁신 시간 확보, 집합 기반 개발, 엔지니어와 최종 사용자 연결이다.

CFO와 예산(9.1.4)이 따로 붙는 이유는, 프로젝트가 아니라 제품으로 생각하라는 말이 예산 편성 방식까지 바꾸자는 주장이기 때문이다. 아키텍처 퀀텀의 크기와 비용의 관계를 다룬다.

비즈니스 사례 (9.2)

가설 주도 개발과 데이터 주도 개발을 다루고, 피트니스 함수를 실험적 매체로 쓰는 사례 넷을 든다. UDP 통신, 보안 의존성, 동시성, 정확성이다.

엔터프라이즈 피트니스 함수 구축 (9.3)

제로데이 보안 취약점 사례연구가 붙는다. 조직 전체 파이프라인에 검사를 한 번 넣어 두면 모든 서비스가 그것을 물려받는다는 이야기다. 기존 통합 아키텍처 안에서 경계 콘텍스트를 떼어내는 방법도 여기서 다룬다.

시작 지점 (9.4)

네 갈래를 제시한다.

  • 낮게 매달린 과일(9.4.1): 가장 덜 얽혀 있고 중요 경로가 아닌 것으로 시작해 개념 증명으로 쓴다
  • 최대 가치 우선(9.4.2): 가장 중요한 부분에서 먼저 검증한다
  • 테스트(9.4.3): 구조를 손대기 전에 굵은 단위의 기능 테스트를 먼저 깐다
  • 인프라스트럭처(9.4.4): 배포·운영이 망가져 있으면 그것부터 고친다

PenultimateWidgets의 엔터프라이즈 아키텍처 사례연구가 붙는다.

미래 전망 (9.5)

AI를 활용한 피트니스 함수, 그리고 생성 테스트다.

되는 이유와 안 되는 이유 (9.6)

마지막 두 소절이 이 책의 균형을 잡는 자리다. 소절 제목은 목차로 확인했고, 각 소절이 나열하는 항목은 공개 스터디 정리를 통해 확인한 것이라 본문과 순서나 표현이 다를 수 있다.

구축하는 이유(9.6.1)로 드는 것: 예측성보다 진화성, 확장성, 고급 비즈니스 기능, 비즈니스 지표로서의 순환 주기, 퀀텀 수준에서 아키텍처 특성을 격리하는 것, 그리고 적응과 진화의 구분.

구축하지 않는 이유(9.6.2)로 드는 것: 커다란 진흙 공은 진화시킬 수 없다는 것, 다른 아키텍처 특성이 지배적인 경우, 의도적으로 희생적 아키텍처를 짓는 경우, 곧 폐업할 비즈니스인 경우. 새로 개편할지 진화시킬지를 가르는 기준으로는 모듈성을 든다.

마지막 항목이 이 목록의 성격을 보여 준다. 이 책의 주장이 언제나 옳다고 말하지 않는다.

새로 나오는 이름

  • 교차기능팀, 인지 부하, 프로젝트를 넘어 제품으로
  • 팀 토폴로지 네 패턴, 집합 기반 개발
  • 엔터프라이즈 피트니스 함수, 생성 테스트
  • 낮게 매달린 과일, 커다란 진흙 공

확인 못 한 것

이 장에 실린 사례연구들의 실제 내용은 대부분 확인하지 못했다. 위에 적은 것은 사례의 제목과 그 제목이 놓인 자리까지다.


정리해 두고 싶은 것

이 책은 하나를 관통한다. 아키텍처 결정을 문서가 아니라 실행 가능한 검사로 남긴다.

문서로 적힌 규칙은 지켜졌는지 아무도 모른다. 어겼을 때 아무 일도 일어나지 않기 때문이다. 검사로 적힌 규칙은 어기면 빌드가 깨진다.

저자들이 피트니스 함수라는 이름으로 한 일은, 이미 있던 테스트·지표·모니터링을 아키텍처 거버넌스의 수단으로 다시 자리매김한 것이다. 4장의 진단이 이것을 가장 직설적으로 말한다. 실행이 뒤따르지 않는 원칙은 의미가 없다.

두 번째로, 진화 가능성은 커플링의 문제다. 2판이 구조를 다루는 부를 따로 둔 이유가 이것이다. 무엇을 바꿀 때 무엇이 함께 바뀌어야 하는지가 곧 그 아키텍처가 얼마나 진화할 수 있는지다.

동조성이라는 어휘를 먼저 세우는 이유도 여기 있다. 커플링을 있다·없다로 말하면 아무 판단도 못 하고, 등급으로 말해야 무엇부터 끊을지 정할 수 있다.

세 번째로, 저자들은 이 접근이 언제나 옳다고 말하지 않는다. 9.6.2에서 하지 말아야 할 경우를 직접 나열한다.

참고 자료

책 정보

저자가 공개한 자료

공개 스터디 정리와 서평

본문의 인용 중 미리보기에서 직접 확인하지 못한 것은 아래 자료를 통해 확인했다. 개인이 정리한 것이므로 원문과 다를 수 있다.

관련 문서: [[building-microservices]] · [[designing-data-intensive-applications]] · [[modern-software-engineering]] · [[distributed-transaction]]