10 minute read

선을 긋고 왼쪽에는 이론이라 적고 오른쪽에는 실무라고 적는다. 내가 읽은 책을 나열해 보면 왼쪽보다는 오른쪽에 많이 치우쳐져 있다. 균형을 잡고 싶어서 이론에 더 가까운 소프트웨어 아키텍처 책을 집어 들었다. 책 제목에 101이 붙어 있어서 더 안심이 된다.

’레이어드 아키텍처 스타일’, ’파이프라인 아키텍처 스타일’, ’마이크로커널 아키텍처 스타일’, ’서비스 기반 아키텍처 스타일’, ’이벤트 기반 아키텍처 스타일’, ’공간 기반 아키텍처 스타일’, ’마이크로서비스 아키텍처 스타일’을 이해하기 쉽게 설명해서 정리할 수 있었다.

아키텍처 스타일을 설명하고 항상 특성 등급을 평가하고 마무리한다. ’분할 유형, 퀀텀 수, 배포성, 탄력성, 진화성, 내고장성, 모듈성, 전체 비용, 성능, 신뢰성, 확장성, 단순성, 시험성’과 같은 낯선 용어들에 익숙해졌다. 아키텍처를 선택할 때 판단 기준으로 유용하게 쓸 수 있는 특성들이다.

아키텍처에 대한 설명이 재미있고 좋았지만 나는 아키텍트에 대해 설명하는 챕터를 더 재미있게 읽었다.

소프트웨어 아키텍트가 무엇을 하는 사람인가는 소프트웨어 아키텍처만큼이나 정의하기가 어렵고, 전문 프로그래머부터 회사의 전략적 기술 방향을 결정하는 것까지 매우 다양합니다. 그래서 우리는 정답도 없는 문제에 우왕좌왕하기보다 사람들이 아키텍트에게 바라는 ’기대치(expectations)’에 집중하고자 합니다.

  • 아키텍처 결정을 내린다
  • 아키텍처를 지속적으로 분석한다
  • 최신 트렌드를 계속 유지한다
  • 아키텍처 결정의 컴플라이언스(compliance)를 보장한다
  • 다양한 기술과 경험에 노출된다
  • 비즈니스 도메인 지식을 보유한다
  • 대인 관계 기술이 뛰어나다
  • 정치를 이해하고 처세를 잘한다

    p.33

답도 없는 문제에 시간을 낭비하지 말자. 만약 아키텍트가 있다면 우리는 그 사람에게 뭘 바랄까? 이런 접근으로 아키텍트가 해야 할 일을 정의한다. 해야 할 일을 정의하면 한 문장으로 아키텍트를 멋지게 정의하지 않아도 괜찮다. 해야 할 일이 명료하니 각자 자신의 언어로 정의해도 아키텍트가 하는 일은 똑같을 것이다. 이 단락을 읽고 책의 남은 내용에 대한 기대가 높아졌다.

아키텍트는 개발팀을 기술적으로 이끌기만 하는 사람이 아니라, 개발팀을 리드해서 아키텍처를 구현하는 사람이므로 아키텍트라는 직책 또는 역할과 상관없이, 리더십 스킬은 소프트웨어 아키텍트로서 성공하기 위해 필수 요구사항의 절반 이상은 차지합니다.

우리는 기술적으로는 흠잡을 데 없이 우수하지만, 팀을 리드, 코치하고 개발자를 멘토링하면서 아키텍처 결정과 설계 원칙, 배경 사상을 효과적으로 전달할 능력이 결여된 소프트웨어 아키텍트를 벌써 여럿 만나봤습니다. 말할 나위도 없이 이런 사람들은 아키텍트 자리에 계속 앉아 있기가 어렵습니다.

p.37

기술적으로는 뛰어나지만 인간관계가 서툴다. 혹은 매니징 능력이 떨어진다. 이런 사람을 아키텍트로 앉히면 불행이 시작된다. 리더십 스킬이 절반 이상을 차지한다는 이 설명이 무엇보다 와닿았다. 맞아 이게 우리가 흔히 하는 착각이다. 매니징을 못 해서 아키텍트를 하는 게 아니라 더 넓은 범위에 영향을 주기 위해 매니징을 안 한다고 해야 더 맞는 표현이 될 것 같다.

아키텍트의 사고방식은 크게 네 가지로 나뉩니다. 첫째, 아키텍처와 설계 차이를 이해하고 아키텍처 작업을 진행하려면 개발팀과 어떻게 협력해야 할지 아는 것입니다. 둘째, 어느 정도 기술 깊이를 유지하면서 폭넓은 기술 지식을 확보하는 것입니다. 그래서 아키텍트는 다른 사람들이 보지 못하는 해결책과 가능성을 떠올릴 수 있습니다. 셋째, 다양한 솔루션과 기술 간의 트레이드오프를 이해하고, 분석하고, 조율하는 것입니다. 넷째, 비즈니스 동인(business driver)의 중요성을 이해하고 그것을 아키텍처 관심사로 해석할 줄 아는 것입니다. p.52

넷째가 와닿는다. 우리는 기술 놀음을 하려고 무언가를 만드는 게 아니다. 뜬구름 잡는 것 같고 허황된 요구사항을 깎아서 현실감 있게 바꾸는 게 비즈니스에 기여할 수 있는 전부가 아니다. 새로운 비즈니스 옵션을 먼저 제공할 수도 있어야 한다. 예전에 같이 일했던 R이 특히 많이 강조했었다. 그는 자주 우리가 보스에게 새로운 비즈니스 옵션을 제공할 수 있어야 한다고 강조하곤 했다.

아키텍트가 실무 경험을 유지하기 위해 어떻게 병행할 수 있는지를 알려준다. 실무 감각을 유지하고 싶은 프로그램팀 매니저에게도 유용한 팁이다. 상대적으로 우선순위가 떨어지는 비즈니스 기능을 코딩하라. PoC(Proof of Concept)를 자주 해봐라. Technical Debt을 갚는 우선순위가 낮은 일들을 진행하라. 개발 효율을 높이는 도구나 분석기를 만들어라. 코드 리뷰를 자주 해봐라. 개발 스케쥴의 크리티컬 패스에만 놓이지 않는 프로그래밍과 관련된 모든 일이다.

’소프트웨어 아키텍처 101’이라고 하기에 부족함이 없는 책이다. 용어 정리를 칼같이 하는 저자의 철저함도 마음에 든다. 저자가 쓴 다른 책이 없나 찾아보니 ’소프트웨어 아키텍처 The Hard Parts (닐 포드 et al., 2022)’가 있다. 이것도 읽어볼 계획이다.

밑줄

  • 소프트웨어 개발 생태계는 일정한 동적 평형(dynamic equilibrium) 상태로 존재합니다. 즉, 어느 시점에서는 균형이 잡힌 상태이지만 장기적으로는 동적인 움직임을 나타냅니다. 이러한 생태계의 특성을 가장 잘 보여주는 예로, 요즘 대세인 컨테이너화(containerization)와 그로 인한 변화가 있습니다. … 하나의 작은 변화가 또 다른 작은 변화를 일으키고, 그런 일이 수백 회 반복되면 또 다른 생태계가 새로 탄생합니다. p.8
  • 아키텍트는 이전 시대에서 물려받은 가정과 공리에 의문을 제기할 중요한 책임이 있습니다. 소프트웨어 아키텍처를 주제로 한 책은 대부분 요즘 세상과는 거리가 먼 시대에 저술됐습니다. 사실 우리는 개선된 엔지니어링 프랙티스(engineering practice), 운영 생태계, 소프트웨어 개발 프로세스 관점에서 정기적으로 기본 공리에 의문을 가져야 한다고 믿습니다. 아키텍트와 개발자가 매일 작업하는 난잡한 동적 평형을 이루는 모든 것들에 대해서 말입니다. p.8
  • 소프트웨어 아키텍트가 무엇을 하는 사람인가는 소프트웨어 아키텍처만큼이나 정의하기가 어렵고, 전문 프로그래머부터 회사의 전략적 기술 방향을 결정하는 것까지 매우 다양합니다. 그래서 우리는 정답도 없는 문제에 우왕좌왕하기 보다 사람들이 아키텍트에게 바라는 ’기대치(expectations)’에 집중하고자 합니다. 아키텍처 결정을 내린다. 아키텍처를 지속적으로 분석한다. 최신 트렌드를 계속 유지한다. 아키텍처 결정의 컴플라이언스(compliance)를 보장한다. 다양한 기술과 경험에 노출된다. 비즈니스 도메인 지식을 보유한다. 대인 관계 기술이 뛰어나다. 정치를 이해하고 처세를 잘한다. p.33
  • 컴플라이언스 보장이란, 아키텍트가 정의하고 문서화하여 전달한 아키텍처 결정과 설계 원칙들을 개발팀이 제대로 준수하고 있는지 지속적으로 확인한다는 뜻입니다. p.36
  • 아키텍트는 개발팀을 기술적으로 이끌기만 하는 사람이 아니라, 개발팀을 리드해서 아키텍처를 구현하는 사람이므로 아키텍트라는 직책 또는 역할과 상관없이, 리더십 스킬은 소프트웨어 아키텍트로서 성공하기 위해 필수 요구사항의 절반 이상은 차지합니다. … 우리는 기술적으로는 흠잡을 데 없이 우수하지만, 팀을 리드, 코치하고 개발자를 멘토링하면서 아키텍처 결정과 설계 원칙, 배경 사상을 효과적으로 전달할 능력이 결여된 소프트웨어 아키텍트를 벌써 여럿 만나봤습니다. 말할 나위도 없이 이런 사람들은 아키텍트 자리에 계속 앉아있기가 어렵습니다. p.37
  • 아키텍트가 내린 거의 모든 결정은 사람들의 반발에 부딪히게 마련입니다. 아키텍처 결정을 실천하려면 당연히 시간과 비용이 들여야 하므로 제품 오너, 프로젝트 관리자, 비즈니스 이해 담당자들의 뭇매를 맞게 될 수밖에 없죠. 또 자기들의 방식이 더 낫다고 주장하는 개발자들의 공격도 피할 수 없습니다. 그래도 아키텍트는 회사에서 정치를 잘하면서 대부분의 결정을 사람들이 수용하도록 기본적인 협상 기술을 발휘해야 합니다. 사실, 소프트웨어 아키텍트는 이런 점들이 상당히 불만입니다. 개발자들은 그들이 결정한 바에 대해 누군가의 승인이나 검토를 받을 필요가 없으니까요. p.39
  • ’알려진 기지의 것들(known knowns)’, 즉 우리가 알고 있다는 사실을 알고 있는 것들입니다. 그리고 ’알려진 미지의 것들(known unknowns)’, 즉 우리가 모르는 뭔가가 있다는 사실을 알고 있는 것입니다. 하지만 여기서 하나 더, ’알려지지 않는 미지의 것들(unknown unknowns)’도 있습니다. 우리가 모른다는 사실조차 알지 못하는 것들이죠 - 도널드 럼즈펠드, 전 미국 국방부 장관 p.42
  • 모든 아키텍처는 알려지지 않은 미지의 것들 때문에 자꾸 되풀이되는데, 애자일은 단지 이것을 인지해서 더 빨리 수행하는 것이다. 그러므로 프로세스는 아키텍처와 거의 분리되어 있지만 소프트웨어 아키텍처의 속성상 반복적인 프로세스가 잘 맞습니다. p.40
  • 소프트웨어 아키텍처의 모든 것은 다 트레이드오프다. - 소프트웨어 아키텍처 제1법칙 p.47
  • 아키텍트가 트레이드오프 아닌 뭔가를 발견했다고 생각한다면 그것은 그가 아직 트레이드오프를 발견하지 못했다는 증거일 가능성이 높다. - 제 1 정리 p.48
  • ’어떻게’보다 ’왜’가 더 중요하다. - 소프트웨어 아키텍처 제2법칙 p.48
  • 아키텍트의 사고 방식은 크게 네 가지로 나뉩니다. 첫째, 아키텍처와 설계 차이를 이해하고 아키텍처 작업을 진행하려면 개발팀과 어떻게 협력해야 할지 아는 것입니다. 둘째, 어느 정도 기술 깊이를 유지하면서 폭넓은 기술 지식을 확보하는 것입니다. 그래서 아키텍트는 다른 사람들이 보지 못하는 해결책과 가능성을 떠올릴 수 있습니다. 셋째, 다양한 솔루션과 기술 간의 트레이드오프를 이해하고, 분석하고, 조율하는 것입니다. 넷째, 비즈니스 동인(business driver)의 중요성을 이해하고 그것을 아키텍처 관심사로 해석할 줄 아는 것입니다. p.52
  • 여러분이 유능한 소프트웨어 아키텍트로서 병목 트랩에 안 빠지려면 먼저 크리티컬 패스와 프레임워크 코드는 다른 개발팀 사람에게 넘기고 비즈니스 기능을 코딩하는 작업에 집중해서 1~3회 이터레이션을 수행하는 것이 좋습니다. 이렇게 하면 세 가지 측면에서 긍정적인 효과가 있습니다. 첫째, 아키텍트는 더 이상 팀의 병목점이 되지 않고 프로덕션 코드를 실제로 작성하는 실무 경험을 쌓게 됩니다. 둘째, 크리티컬 패스와 프레임워크 코드를 개발팀에 분산시키고 소유권을 부여함으로써 시스템에서 가장 어려운 부분을 더 잘 이해할 수 있습니다. 셋째가 아마도 가장 중요한 장점인데, 아키텍트가 개발팀에서 작업 중인 비즈니스 연관 코드를 직접 작성함으로써 개발자들이 프로세스, 절차, 개발환경, 어느 부분에서 가장 큰 고통을 겪고 있는지 몸소 체험할 수 있습니다. p.64
  • PoC(Proof of Concept)를 자주 해보는 것입니다. PoC는 아키텍트가 소스 코드를 직접 작성해보면서 구현 상세를 생각하게 되므로 아키텍처 결정을 검증하는 데 유용합니다. 예를 들어, 두 가지 캐시 솔루션을 두고 갈팡질팡하고 있는 아키텍트가 결정 장애를 극복하는 가장 좋은 방법은, 실제로 각 제품을 응용한 예제 코드를 짜보고 실행 결과를 비교해보는 겁니다. p.65
  • 응집(Cohesion)은 한 모듈의 파트가 동일한 모듈 안에 얼마나 포함되어 있는지를 나타냅니다. 다시 말해, 모듈을 구성하는 파트가 서로 얼마나 연관되어 있는가 하는 것입니다. 이상적으로 응집된 모듈이라면 모든 파트가 함께 패키징되어 있겠죠. 파트를 더 잘게 쪼개려면 모듈 간 호출을 통해 파트를 묶어야 유용한 결과를 얻을 수 있기 때문입니다. p.71
  • 응집된 모듈을 나누려고 해봐야 더 커플링되고 가독성은 떨어진다. - 래리 콘스탄틴 p.71
  • 두 컴포넌트 중 한쪽이 변경될 경우 다른 쪽도 변경해야 전체 시스템의 정합성이 맞는다면 이들은 커네이선스(Connascence)를 갖고 있는 것이다. - 밀러 페이지-존스 p.80
  • 아키텍처에서는 틀린 답은 없고 값비싼 답만 있습니다! p.111
  • 레이어드 아키텍처는 가장 흔한 아키텍처 스타일 중 하나입니다. 단순하고 대중적이면서 비용도 적게 들어 모든 애플리케이션의 사실상 표준(de facto standard) 아키텍처입니다. 시스템을 설계하는 조직은 그 조직의 소통 구조를 그대로 복제한 듯 설계할 수밖에 없다는 콘웨이의 법칙을 떠올려보면, 레이어드 아키텍처는 애플리케이션을 개발하는 아주 자연스러운 방법입니다. UI 개발자, 백엔드 개발자, 규칙 개발자, 데이터베이스 전문가(DBA)는 어느 회사건 다 있고 이런 조직의 계층 구조가 전통적인 레이어드 아키텍처와 잘 맞아떨어지니 많은 사랑을 받게 된 것입니다. p.181
  • 레이어드 아키텍처는 (도메인 분할 아키텍처의 반대인) 기술 분할된 아키텍처입니다. 즉, 컴포넌트를 (고객 같은) 도메인 단위로 묶는 게 아니라, 아키텍처의 (프레젠테이션 또는 비즈니스 같은) 기술 역할에 따라 묶기 때문에 비즈니스 도메인이 각각 모든 아키텍처 레이어에 분산됩니다. 예를 들어, ’고객’ 도메인은 프레젠테이션, 비즈니스, 규칙, 서비스, 데이터베이스 모든 레이어에 다 포함되므로 이 도메인에 어떤 변경을 가하는 일이 쉽지 않습니다. 이런 이유로 이 아키텍처 스타일은 도메인 주도 설계 방식과는 잘 안 맞습니다. p.183
  • 레이어드 아키텍처의 각 레이어는 폐쇄(closed) 또는 개방(open) 상태입니다. 폐쇄 레이어(closed layer)란, 요청이 상위 레이어에서 하위 레이어로 이동하므로 중간의 어떤 레이어도 건너뛸 수 없고 현재 레이어를 거쳐야 바로 그 다음 레이어로 나아갈 수 있다는 뜻입니다. p.185
  • 레이어드 아키텍처에서는 아키텍처 싱크홀(architecture sinkhole) 안티패턴을 조심해야 합니다. 요청이 한 레이어에서 다른 레이어로 이동할 때 각 레이어가 아무 비즈니스 로직도 처리하지 않고 그냥 통과시키는 안티패턴을 말합니다. p.187
  • 레이어드 아키텍처 기반의 애플리케이션은 규모가 커질수록 유지 보수성, 민첩성, 시험성, 배포성 같은 아키텍처 특성이 점점 나빠집니다. 따라서 레이어드 아키텍처를 사용한 대규모 애플리케이션이나 시스템은 다른 더 모듈러한 아키텍처 스타일이 더 잘 맞습니다. p.189
  • 대부분의 개발자는 이 아키텍처를 Bash나 Zsh 같은 터미널 쉘 언어의 기초 원리임을 알고 있습니다. 함수형 언어 개발자는 언어 구조와 이 아키텍처 요소가 유사하다고 생각할 것입니다. 사실 맵리듀스(MapReduce) 프로그래밍 모델을 응용한 많은 도구가 이 기본 토폴로지를 따릅니다. 이처럼 파이프라인 아키텍처 스타일은 저수준에서 구현할 수도 있고 고수준의 비즈니스 애플리케이션에도 적용할 수 있습니다. p.193
  • 마이크로커널 아키텍처 스타일은 코어 시스템(core system)과 플러그인 컴포넌트(plug-in component)라는 두 가지 아키텍처 요소로 구성된 비교적 단순한 모놀리식 아키텍처입니다. 애플리케이션 로직은 독립적인 플러그인 컴포넌트와 기본 코어 시스템에 골고루 분산되어 확장성, 적응성, 애플리케이션 기능 분리, 커스텀 처리 등을 수행합니다. p.201
  • 이클립스 IDE, PMD, Jira, Jenkins 등 많은 소프트웨어 개발/릴리즈 도구가 마이크로 커널 아키텍처를 사용해서 개발됐습니다. Chrome, Firefox 같은 인터넷 웹 브라우저도 마이크로커널 아키텍처를 응용한 제품으로, 각종 뷰어와 플러그인을 장착하면 코어 시스템에 해당하는 기본 브라우저에 없는 부가 기능을 덧붙일 수 있습니다. p.211
  • 서비스 기반 아키텍처(Service-based architecture)는 마이크로서비스 아키텍처 스타일의 일종으로, 아키텍처가 유연해서 가장 실용적인 아키텍처 스타일 중 하나입니다. 마이크로서비스나 이벤트 기반 아키텍처와 마찬가지로 분산 아키텍처지만 비교적 덜 복잡하고 비용이 많이 들지 않아서 많은 비즈니스 관련 애플리케이션에 널리 채택된 아키텍처입니다. p.215
  • 서비스 기반 아키텍처는 중앙 공유 데이터베이스를 사용한다는 특징이 중요합니다. 따라서 서비스는 기존 모놀리식 레이어드 아키텍처와 동일한 방식으로 SQL 쿼리와 조인 기능을 사용하면 됩니다. 서비스 개수가 적어서 (4~12개) 데이터베이스 커넥션은 대개 문제가 안 되지만 데이터베이스 자체의 변경은 이슈가 될 수 있는데 p.217
  • 도메인 서비스는 세분도가 큰 까닭에 단일 도메인 서비스에서 데이터 무결성을 보장하기 위해 커밋/롤백이 수반되는 여느 ACID 데이터베이스 트랜잭션을 사용하지만, 마이크로서비스처럼 분산도가 높은 아키텍처는 서비스를 더 잘게 나누어 BASE 트랜잭션(기본적 가용성, 소프트 상태, 최종 일관성)이라고 알려진 분산 트랜잭션 기법을 사용합니다. 이 기법은 그 기반이 최종 일관성이므로 서비스 기반 아키텍처의 ACID 트랜잭션 레벨의 데이터 무결성을 지원하지 않습니다. p.220
  • 공간 기반 아키텍처 스타일은 높은 확장성, 탄련성, 동시성 및 이와 관련된 문제를 해결하기 위해 설계된 아키텍처 스타일입니다. 동시 유저 수가 매우 가변적이라서 예측조차 곤란한 애플리케이션에서도 유용합니다. 극단적이고 가변적인 확장성 문제는 데이터베이스를 확장하거나, 확장성이 떨어지는 아키텍처에 맞게 캐시 기술을 적용하는 것보다 아키텍처적으로 해결하는 것이 더 낫습니다. p.266
  • 프로그래머 앤드류 케이니그는 안티패턴이란 처음에는 좋은 생각처럼 보이지만 이내 곧 곤경에 빠뜨리는 애물단지라고 정의합니다. 부정적인 결과를 내는 반복 가능한 프로세스라고 정의하는 이들도 있습니다. p.341
  • 이런 활동을 하는 아키텍트의 역할에 의문을 제기하고 팀을 효과적으로 만드는 책임을 PM이나 개발 관리자에게 일임하는 사람도 있습니다. 우리는 강력히 반대합니다. 소프트웨어 아키텍트는 팀을 기술적으로 이끌 뿐만 아니라, 아키텍처 구현을 통해 팀을 리드하기도 합니다. 소프트웨어 아키텍트는 개발팀과 긴밀한 협력 관계를 유지하면서 팀 역학을 관찰하고 변경을 촉진하여 효과적으로 팀을 움직일 수 있습니다. 이것이 바로 기술만 가진 아키텍트와 유능한 소프트웨어 아키텍트를 구분하는 잣대이기도 합니다. p.416
  • 증명(demonstration)은 언제나 논쟁(discussion)을 이긴다는 사실을 명심하세요. p.421
  • 소프트웨어 아키텍트는 개발팀을 이끌고 아키텍처를 구현하는 리더입니다. 유능한 소프트웨어 아키텍트가 되는 50% 정도는 효과적인 대인 관계 스킬, 조정 능력, 리더십에 있다고 생각합니다. p.423
  • 성공의 공식에서 가장 중요한 한 가지 성분은 다른 사람들과 잘 지내는 방법을 아는 것이다. - 시어도어 루즈벨트 p.436
  • 균형을 유지하는 기술로 20분 규칙이 있습니다. 아키텍트로서 커리어를 유지하기 위해 새로운 것을 배우거나 특정 주제를 깊이 파고드는 시간을 매일 최소 20분은 할애하라는 규칙입니다.