BookReview [SoftwareArchitecture 101]
SoftwareArchitecture 101
아키텍트가 되기 위한 책으로 최근에 나온 책이기에 시대가 발전해가면서 아키텍트로서의 역량과 가치관을 담고 있다.
모놀리식 아키텍처와 분할 아키텍처(마이크로 서비스 등등)에 대한 이해도와 아키텍처란 무엇일까에 대한 생각을 정리하기 좋았던 책이다.
읽게된 이유는 진행중인 책 모임 아카데미 컨퍼런스의 3회차 책으로 읽게 되었는데 나에겐 너무 어렵다고 느껴져서 조금 힘들었다.
그렇다고 대충 읽은 건 아니고 계속 읽다보니 서서히 눈에 들어오고 이해가 되는 부분도 있었다.
누구나 처음 배우는 부분은 다 그런게 아닐까..
또한 이런 지식 자체가 인사이트를 공유하기에도 좋고 다른 개발자의 말을 듣기에도 좋은 내용이라 아키텍처에 대한 시야를 트고 싶다면 추천한다.
1. 서론
소프트웨어 아키텍트란 무슨 직업일까..?
다른 직업에 비해 커리어패스가 불분명한지..?
- 많은 사람들이 직업 자체에 대한 정의를 잡지 않았으며 추상적으로 말하곤 한다.
아키텍처는 중요한 것들에 관한 것이다. 그게 무엇이든 말이다.
-
소프트웨어 아키텍트는 매우 방대한 분야를 포괄하며 업무의 범위또한 매우 넓다.
-
소프트웨어 개발 생태계는 워낙 빠르게 발전하는 분야이고 소프트웨어 아키텍처는 끊임없이 변화하기 때문
소프트웨어 아키텍처는 본질 자체가 동적이다.
- 소프트웨어 아키텍처에 관한 자료는 대부분 역사적인 연관성을 강조한다.
정리하면 소프트웨어 아키텍트는 끊임없이 변화하는 생태계안에서 뭔가 결정을 내리는 사람들입니다.
아키텍처를 공부하는 사람들이 명심해야 하는 부분은 예술과 마찬가지로 콘텍스트로서만 이해할 수 있다는 것입니다.
모든 아키텍처는 그 콘텍스트의 결과물이라는 사실.
1.1 소프트웨아 아키텍처란?
시스템의 청사진, 이정표정도의 개념이고, 아키텍트는 시스템을 분석
한다면 과연 무엇을 분석한다는 것 일까?
아키텍처를 바라보는 한 가지 방법으로 아키텍처 특성, 아키텍처 결정, 설계 원칙, 시스템 구조의 형태로 보는 방법
- 시스템 구조란?
마이크로서비스, 레이어드, 마이크로 커널 같은 아키텍처 스타일을 말한다.
- 아키텍처 특성이란?
일반적으로 시스템의 기능과 직교하는 성공 기준을 결정
가용성, 신뢰성, 시험성, 확장성, 보안, 민첩성, 내고장성, 탄력성, 복구성, 성능, 배포성, 학습성..
나열된 특성이 시스템 기능에 관한 지식을 필요로 하는 것은 아니지만, 시스템이 올바르게 동작하기 위해서는 반드시 필요한 것이다.
- 아키텍처 결정이란?
아키텍처 결정은 시스템 구축에 필요한 규칙들을 정의한 것
ex) 아키텍트가 레이어드 아키텍처에서는 프레젠테이션 레이어가 데이터베이스를 직접 호출하지 못하게 비지니스와 서비스 레이어에서만 데이터베이스를 액세스할 수 있다고 결정하는 식이다.
- 설계 원칙이란?
아키텍처 결정이 반드시 지켜야 할 규칙이라면 설계 원칙은 가이드라인이다.
1.2 아키텍트에 대한 기대치
앞서 말한 것과 같이 아키텍트의 역할은 단순하게 정의하기 어렵기 때문에 대부분의 사람들이 아키텍트에게 바라는 기대치
에 집중한다.
역할, 직책, 직무 상관없이 소프트웨어 아키텍트에게 바라는 핵심적인 요구사항은 다음과 같다.
- 아키텍처 결정을 내린다.
- 아키텍처를 지속적으로 분석한다.
- 최신 트렌드를 계속 유지한다.
- 아키텍처 결정의 컴플라이언스를 보장한다.
- 다양한 기술과 경험에 노출된다.
- 비지니스 도메인 지식을 보유한다.
- 대인 관계 기술이 뛰어나다.
- 정치를 이해하고 처세를 잘한다.
한마디로 뛰어난 사람..!
유능한 소프트웨어 아키텍트가 되려면 이렇게 사람들이 자신에게 바라는 요구사항을 충분히 실천하려는 마음가짐을 가져야 한다.
1.2.1 아키텍처 결정을 내린다
아키텍트는 아키텍처와 설계 원칙을 결정하고 팀, 부서뿐만 아니라 회사 전체의 기술 결정을 가이드하는 사람입니다.
첫 번째 요구사항은의 키워드는 가이드
이다.
아키텍트는 기술 선택을 가이드하는 사람이지, 정해주는 사람이 아니다..!
이러한 과정은 생각보다 어렵기 때문에 자신이 내린 결정에 대한 자문을 해봐야 한다.
1.2.2 아키텍처를 지속적으로 분석한다
아키텍트는 끊임없이 아키텍처와 현재 기술 환경을 분석하고 이를 개선하기 위한 해결 방안을 제시합니다.
3년전에 정의한 아키텍처가 지금도 얼마나 현실성 있는지 평가하는 아키텍처 역동성에 관한 요구사항이다.
경험에 비추어 봐도 예전 아키텍터를 지속적으로 분석하는 데 에너지를 집중하는 아키텍트는 별로 보지 못했다.
그래서 대부분의 아키텍처 구조가 쇠락하는 양상을 보이며 특히 성능, 가용성, 확장성 등의 필수 아키텍처 특성에 영향을 미치는 코드를 개발자가 작성하거나 설계를 변경할 때 이런 증상이 나타난다..
여기서도 TDD 교조주의에 관한 내용이 나오는 것 같다.
개발자의 위치에서의 테스팅과 아키텍처의 거시적 관점이 다르다.
따라서 아키텍트라면 지속적인 분석을 통해 애플리케이션을 계속 적절하게 유지할 수 있는 능력을 갖고 있어야 한다.
1.2.3 최신 트렌드를 계속 유지한다
아키텍트는 항상 최신 기술과 업계 트렌드를 따라가야 합니다.
아키텍트는 최신 기술과 업계 트렌드를 따라가야 하는, 한층 더 중요한 요구사항을 달성해야 한다.
아키텍트가 결정한 것들은 대개 오래 지속되고 바꾸기도 어렵다,,!
1.2.4 아키텍처 결정의 컴플라이언스를 보장한다
아키텍트는 아키텍처 결정과 설계 원칙의 컴플라이언스를 보장해야 한다.
컴플라이언스 보장이란, 아키텍트가 정의하고 문서화하여 전달한 아키텍처 결정과 설계 원칙들을 개발팀이 제대로 준수하고 있는지 지속적으로 확인한다는 뜻
1.2.5 다양한 기술과 경험에 노출된다
아키텍트는 다양한 기술, 프레임워크, 플랫폼, 환경에 노출되어야 합니다.
아키텍트가 모든 프레임워크, 플랫폼, 언어에 통달해야 할 필요는 없지만, 적어도 다양한 기술을 거리낌없이 쓸 줄 알아야 한다..
그러려면 아키텍트 자신이 가장 익숙한 영역을 점점 넓혀가는 것이 가장 좋다.
한 가지 기술이나 플랫폼에만 올인하는 것은 안일한 태도..
1.2.6 비지니스 도메인 지식을 보유한다
아키텍트는 어느 수준 이상의 비즈니스 도메인 전문가여야 한다.
유능한 소프트웨어 아키텍트는 기술은 물론이고 문제 영역의 비즈니스 도메인도 잘 알고 있다.
해결하고자 하는 문제 영역, 핵심 비즈니스 요구사항
1.2.7 대인 관계 기술이 뛰어나다
아키텍트는 팀워크, 조정, 리더십을 포함한 대인관계 기술이 뛰어나야 합니다.
1.2.8 정치를 이해하고 처세를 잘한다
아키텍트는 기업 내부의 정치적 분위기를 이해하고 적절하게 잘 처신할 줄 알아야 합니다.
1.3 아키텍처의 교차점 그리고
소프트웨어 아키텍처는 지난 10년 동안 더 많은 책임과 관점을 아우르는 방향으로 확대되었습니다..
페츠닷컴의 사례처럼 탄력성이 필요한 이유와 사례가 만들어낸 반면교사..?
1.3.1 엔지니어링 프랙티스
과거 소프트웨어 아키텍처는 소프트웨어를 제작하는 개발 프로세스와 분리돼 있었습니다.
폭포수 모델, (스크럼, 익스트림 프로그래밍, 린, 크리스털 같은)애자일등 소프트웨어를 구축하는 인기 있는 방법론은 소프트웨어 아키텍처에 그리 큰 영향을 끼치지 못했습니다.
그러나 발전을 거듭하며 엔지니어링 프랙티스와 소프트웨어 개발 프로세스는 구분을 해야함을 깨닫게 되었습니다.
프로세스는 팀을 어떻게 구성하고 관리하는지 회의는 어떻게 하고 워크플로 조직은 어떻게 운영할지 등 사람을 조직하고 상호작용하는 총체적인 기법입니다.
반면 소프트웨어 엔지니어링 프랙티스는 프로세스와 무관하게 가시적이고 반복 가능하 혜택을 주는 실천론입니다.
지속적 통합은 특정 프로세스에 의존하지 않고 검증된 엔지니어링 프랙티스입니다.
엔지니어링 프랙티스에 집중하는 것은 중요하다
- 소프트웨어 개발 분야는 보다 성숙한 다른 엔지니어링 체계에 있는 많은 특성들이 빠져 있습니다.
- 소프트웨어 개발의 아킬레스 건 중 하나는 추정이다.
추정에 대한 공감.
‘알려진 기지의 것들’, 즉 우리가 알고 있다는 사실을 알고 있는 것
‘알려진 미지의 것들’, 즉 우리가 모르고 있다는 사실을 알고 있는 것들
‘알려지지 않은 미지의 것들’ 즉 우리가 모른다는 사실도 모르는 것
여기서 알려지지 않은 미지의 것들
은 소프트웨어에서 필연적인 것이다.
때문에 빅 디자인 업 프린트(설계부터 확실하게)를 실천하기 어렵다..
모든 아키텍처는 알려지지 않은 것들 때문에 자꾸 되풍이 되는데, 애자일은 단지 이것을 인지해서 더 빨리 수행하는 것이다.
1.3.2 운영/데브옵스
데브옵스의 출현과 더불어 최근 두드러진 아키텍처와 유관 분야 간의 차이점은 아키텍처 공리를 다시 음미한 결과입니다..?
오랫동안 외주를 맡기는 형태로 진행되다 최근에 운영문제와 아키텍처를 결합한 새로운 형태의 아키텍처를 실험하기 시작 -> 마이크로서비스
마이크로서비스 아키텍처 스타일을 정립한 아키텍트들은 운영 관심사는 운영으로 처리해야 더 매끄럽다는 사실을 깨닫게 되었습니다.
1.3.3 프로세스
소프트웨어 아키텍처는 소프트웨어 개발 프로세스에 거의 직교적이라는 공리가 있습니다..
소프트웨어를 구축하는 방법은 사실 소프트웨어 아키텍처에 별다른 영향을 끼치지 않습니다.
1.3.4 데이터
중요한 어플리케이션의 개발은 일반적으로 관계형 데이터베이스 형태의 외부 데이터 스토리지가 큰 비중을 차지하지만, 많은 소프트웨어 아키텍처 도서는 이런 아키텍처의 중요한 영역을 너무 가볍게 다루는 경향이 있다..
코드와 데이터는 공생관계여서 상대방이 없으면 무용지물.
1.4 소프트웨어 아키텍처 법칙
소프트웨어 아키텍처의 범위는 거의 무한에 가까울 정도로 광할하지만 모든 것을 통합하는 요소는 존재한다.
- 제 1법칙: 소프트웨어 아키텍터의 모든 것은 다 트레이드오프다.
- 제 1정리: 아키텍트가 트레이드오프 아닌 뭔가를 발견했다고 생각했다면 그것은 아직 트레이드오프를 발견하지 못했다는 증거일 가능성이 높다.
- 제 2법칙: ‘어떻게’보다 ‘왜’가 더 중요하다.
느낀점
각오는 하고 읽었지만 처음보는 단어도 많고 내용도 어렵다고 걱정해서 그런지 무서웠는데.. 읽어보니 생각보다 잘 읽혀서 다행이다..
물론 서론이라 뒷 부분의 자세한 내용까지는 모르지만 한번 쓱 읽어봐도 처음보는 단어들 빼고는 잘 설명이 되어 있다..!
논의사항
책에 나온 아키텍트에 대한 기대치말고 여러분들이 아키텍트를 볼 때 기대하는 추가적인 부분이나 중요하다고 생각하는 부분이 있을까요?
2. 아키텍처 사고
아키텍트는 개발자와 사뭇 다른 관점에서 주변을 바라본다.
기상학자와 아티스트가 구름을 바라보는 관점이 다른 것과 같은 이치이다.
이를 아키텍처 사고(architecture thinking)라고 한다.
그런데 아키텍처사고를 그냥 아키텍처를 생각하는 것 정도로 단순하게 여기는 아키텍트가 참 많다..
아키텍처 사고는 이보다 훨씬 심오한 것이며, 아키텍처적인 눈으로, 즉 아키텍처 관점에서 사물을 바라보는 것이다.
- 아키텍처와 설계의 차이를 이해하고 아키텍처 작업을 진행하려면 개발팀과 어떻게 협력해야 할지 아는 것이다.
- 어느 정도 기술 깊이를 유지하면서 폭넒은 기술 지식을 확보하는 것이다.
- 다양한 솔루션과 기술 간의 트레이드오프를 이해하고, 분석하고, 조율하는 것이다.
- 비즈니스 동인의 중요성을 이해하고 그것을 아키텍처 관심사로 해석할 줄 아는 것
2.1 아키텍처 대 설계
아키텍처와 설계의 차이점은 사실 모호한 경우가 많지만 아키텍트처럼 사고한다는 것은 비즈니스와 기술 문제를 해결하기 위해 아키텍처와 설계의 차이점을 알고 이 둘을 긴밀하게 통합한 솔루션을 모색하는 것이다.
전통적인 아키텍트 책임과 개발자의 책임
아키텍트는 비지니스 요구사항을 분석해서 아키텍처 특성을 도출/정의하고 아키텍처 패턴과 스타일이 해당 문제 영역에 가장 알맞는지 선택하여 각종 컴포넌트를 만든다.
이러한 결과를 개발팀에 전달하면, 개발팀은 각 컴포넌트 클래스 다이어그램을 그린 뒤 UI화면을 만들고 소스코드를 개발/테스트한다..
하지만 이런 구조는 아키텍트와 개발자를 나누는 물리적 장벽, 그리고 그걸 관통하는 아키텍트의 단방향 화살표가 문제다..!
제대로 된 아키텍처를 만들려면 반드시 아키텍트와 개발자를 가르는 물리적 장벽을 허물고 두 팀이 양방향으로 소통하는 관계를 정립해야 한다.
2.2 기술 폭
기술 세부 범위 또한 개발자와 아키텍트가 다르다.
업무를 진행하기 위해 기술 깊이를 확보해야 하는 개발자와 달리, 소프트웨어 아키텍트는 아키텍트답게 사고하고 아키텍처시각을 유지하기 위해 상당한 기술 폭을 갖춰야 한다.
개발자는 전문성을 계속 유지해야 한다. 반면 아키텍트는 기술의 폭을 넓혀야 한다.
커리어 내내 자신의 기술을 갈고 닦아온 개발자가 아키텍트로 전환하려면 우선 관점부터 바꾸어야 한다…
그런데 의외로 많은 사람들이 이것을 어려워하기 때문에 결국 두 가지 역효과 일어난다.
- 아키텍트가 되어 다양한 분야에서 전문성을 유지하려고 하나, 어느 하나도 성공하지 못한 채 그러는 도중 지레 지쳐버린다.
- 김빠진 전문성이 나타나는데 이는 회사 창립 개발자들이 리더가 되어도 아직도 옛날 기준으로 기술 결정을 내리는 것
2.3 트레이드오프 분석
아키텍트처럼 생각하는 것은 기술 여부와 상관없이 모든 솔루션의 트레이드오프를 분석하여 최선의 솔루션을 결정하는 것이다.
아키텍처는 구글링해도 안 되는 것이다.
아키텍처는 모든 게 다 트레이드오프입니다.
아키텍처를 문의할 때 마다 경우에 따라 다르다고 대답하는 이유도 같다..
프로그래머는 장점은 잘 알지만 트레이드오프는 하나도 모른다.
아키텍트는 둘 다 잘 알아야 한다.
아키텍처 사고는 어떤 솔루션의 장점도 보면서 그와 연관된 단점이나 트레이드오프는 없는지 분석합니다..
책에서 주어진 예제를 분석한다면 정답은 경우에 따라 다르다..!
소프트웨어 아키텍처는 만사가 트레이드오프를 갖고 있다는 점이 중요하다.
아키텍트다운 사고란 이런 트레이드오프를 분석하고 신장성과 보안 중에 어느 것이 더 중요한가..?를 떠올려보는 것
여러 솔루션 중 택일하는 것은 언제나 비즈니스 동인, 환경 등 다양한 팩터에 좌우된다.
2.4 비즈니스 동인의 이해
아키텍처 사고는 성공적인 시스템 구축에 필요한 비즈니스 동인을 이해하고 요구사항을 아키텍처 특성으로 해석하는 것이다.
2.5 아키텍처와 코딩 실무 간 균형 맞추기
코딩 실무와 소프트웨어 아키텍처의 균형을 맞추는 것도 아키텍트가 극복해야 할 어려운 일 중 하나이다.
우리는 모든 아키텍트가 코딩을 하면서 어느 정도의 기술 깊이는 유지해야 한다고 생각하지만 매우 어려운 문제이다.
- 병목 트랩에 빠지지 말라
- 개념증명을 자주 해라
- 기술 부채 스토리나 아키텍처 스토리에 전념
- 피트니스 함수 사용
느낀점
개발자로서 아키텍처사고를 기르는 것은 도움이 될 것 같다고 생각하지만, 두개 다 잘하고 싶다는 마음은 불가능 할 것 같다는 생각이 든다.. 마찬가지로 트레이드 오프,,,
논의사항
과연 ChatGPT같은 AI가 언젠간 아키텍트의 분야까지도 위협이 될까요?
범위도 워낙 크고 때에 맞는 판단, 분석력이 필요한 분야라서 아직은 불가능하다고 생각되지만(정형화 된 애플리케이션 제외..) 언젠가는 가능하다고 보시는지..
3. 모듈성
먼저, 모듈성(modularity)을 둘러싼 아키텍처 논쟁에서 자주 사용되는 용어들을 풀이하고 이 책 전체에서 계속 사용할 개념 몇 가지를 정의한다.
소프트웨어 아키텍처 용어의 95%는 ‘모듈성’의 이로움을 찬양하는 데 사용되고 있지만, 정작 모듈성을 어떻게 달성할지에 대해서는 별다른 얘기가 없다.
플랫폼마다 제공하는 코드 재사용 메커니즘은 제각각이지만, 연관된 코드를 모듈
로 묶는 방법은 모두 지원한다.
하지만 모듈성은 쉽게 정의하기 어려운 개념이다.
본인이 선택한 개발 플랫폼에서 모듈성과 그것을 구현한 수많은 코드를 이해하는 것은 아키텍트에게 중요한 일이다.
아키텍처를 분석해야 할 매트릭, 피트니스, 시각화등 많은 도구가 바로 이 모듈성을 기반으로 하기 때문이다.
모듈성을 잘 유지하는 건 우리가 암묵적 아키텍처 특성이라고 정의한 것의 좋은 예가 된다.
즉, 모듈이 확실히 구분되고 모듈 간 통신이 잘 되어야 한다고 공식적으로 아키텍트에게 요구하는 프로젝트는 드물지만, 코드베이스를 잘 발전시켜 나가려면 암묵적으로 질서와 일관성이 필요합니다.
3.1 정의
사전에서 모듈은 ‘복잡한 구조를 만드는 데 쓰이는 각각의 표준화한 부품이나 독립적인 단위’라고 나온다.
우리는 모듈성을 이용해 객체 지향 언어의 클래스나 함수형 언어의 함수가 될 만한 서로 연돤된 코드를 논리적으로 묶는다.
프로그래밍 언어에서는 대부분 모듈성 메커니즘을 제공하며, 개발자는 보통 연관된 코드를 함께 묶는 수단으로 모듈을 사용한다.
아키텍트는 개발자가 코드를 어떻게 패키징하는지 반드시 알아야 한다.
아키텍처에 중요한 영향을 미치기 때문이다..
여러 패키지가 서로 단단히 커플링되어 있으면 그 중 하나를 다른 작업에 재사용하기 아주 어렵다.
3.2 모듈성 측정
모듈성은 아키텍트에게 중요한 주제이므로 이것을 이해할 도구가 필요하다.
아키텍트가 모듈성을 이해하는 데 도움이 될 만한 다양한 언어 독립적인 메트릭들을 선배들이 만어 놨다.
여기서 세 가지 핵심 개념인 응집, 커플링, 커네이선스를 집중적으로 알아보자
3.2.1 응집
응집(cohesion)은 한 모듈의 파트가 동일한 모듈 안에 얼마나 포함되어 있는지를 나타낸다.
즉, 모듈을 구성하는 파트가 서로 얼마나 연관되어 있는가, 라는 것이다.
응집된 모듈을 나누려고 해봐야 더 커플링되고 가독성은 떨어진다.
응집도의 측정 범위를 정의했는데 가장 좋은 것부터 나쁜 순으로 나열한다.
- 기능적 응집
모듈의 각 파트는 다른 파트와 연관되어 있고 가능상 꼭 필요한 모든 것이 모듈에 들어있다.
- 순차적 응집
두 모듈이, 한쪽이 데이터를 출력하면 다른 한쪽이 그것을 입력받는 형태로 상호작용한다.
- 소통적 응집
두 모듈이, 각자 정보에 따라 작동하고 어떤 출력을 내는 형태로 통신 체인을 형성한다.
예를 들면, 데이터베이스에 레코드를 추가하면 그 정보에 따라 이메일이 만들어지는 식
- 일시적 응집
모듈은 시점 의존성에 따라 연관된다.
예를 들어, 많은 시스템들이 시동할 때 그다지 관련이 없어 보이는 것들을 초기화하는 경우가 많은데, 이런 작업들이 일시적으로 응집됐다고 할 수 있다.
- 논리적 응집
모듈의 내부 데이터는 기능적이 아니라, 논리적으로 연관되어 있다.
이를테면, 텍스트, 직렬화 객체, 스트림 형태로 받은 데이터를 변환하는 모듈이 그렇다.
- 동시적 응집
같은 소스 파일에 모듈 구성 요소가 들어 있지만 그 외에는 아무 연관성도 없다.
이는 가장 좋지 않은 형태의 응집이다.
3.2.2 커플링
코드베이스의 커플링은 그래프 이론에 기반한 좋은 분석 도구들이 많이 있다.
메서드의 호출과 반환은 호출 그래프를 형성하므로 수학적인 분석이 가능하다.
3.2.3 추상도, 불안정도, 메인 시퀀스로부터의 거리
추상도는 추상 아티팩트와 구상 아티팩트의 비율, 즉 구현 대비 추상화 정도를 나타낸다.
가령 추상화를 전혀 하지 않고 하나의 엄청나게 큰 함수 코드가 있는 코드베이스도 있고, 반대로 너무 지나치게 추상화해서 코드가 서로 어떻게 연결되어 있는지 개발자가 파악하기 어려운 코드베이스도 있다.
3.2.4 메인 시퀀스로부터의 거리
메인 시퀀스로부터의 거리는 아키텍처 구조를 평가하는 몇 가지 전체적인 메트릭 중 하나로, 불안정도와 추상도를 이용하여 계산한다.
3.2.5 커네이선스
두 컴포넌트 중 한쪽이 변경될 경우 다른 쪽도 변경해야 전체 시스템의 정합성이 맞는다면 이들은 커네이선스를 갖고 있는 것이다.
정적 커네이선스
소스 코드 레벨의 커플링으로, 구심/원심 커플링을 발전시킨 개념이다.
다시 말해 아키텍트는 구심적이든, 원심적이든 다음 종류의 정적 커네이선스를 뭔가에 커플링된 정도라고 보는 것이다.
- 명칭 커네이선스
여러 컴포넌트의 엔티티명이 일치해야 한다.
메서드명은 코드베이스가 커플링되는 가장 일반적이면서 바람직한 방법이다.
특히, 최신 리팩터링 도구는 대부분 시스템 전체적으로 이름을 바꾸는 기능을 아주 잘 지원한다.
- 타입 커네이선스
여러 컴포넌트의 엔티티 타입이 일치해야 한다.
대부분의 정적 타입 언어에서 변수와 매개변수를 특정 타입으로 제한하는 일반적인 기능이다.
그러나 이것은 언어에 내장된 기능은 아니며, 클로저 또는 클로저 스팩등 선택적 타이핑 기능을 제공하는 동적타입 언어도 있다.
- 의미 커네이선스 또는 관례 커네이선스
여러 컴포넌트에 걸쳐 어떤 값의 의미가 일치해야 한다.
이런 종류의 커네이선스는 상수 대신 숫자를 하드코딩한 코드베이스에서 흔히 발견된다.
- 위치 커네이선스
여러 컴포넌트는 값의 순서가 일치해야 한다.
정적 타이핑이 가능한 언어에서도 메서드와 함수 호출 시 전달하는 매개변수 값은 순서가 맞아야 한다.
- 알고리즘 커네이선스
여러 컴포넌트는 특정 알고리즘이 일치해야 합니다.
흔한 예로, 서버/클라이언트 둘 다 실행되어야 하고 유저 인증 시 반드시 동일한 결과를 내야하는 보안 해시 알고리즘이 그렇다.
동적 커네이선스
동적 커네이선스는 런타임 호출을 분석하는 또다른 유형의 커네이선스입니다.
- 실행 커네이선스
여러 컴포넌트의 실행 순서가 중요하다.
- 시점 커네이선스
여러 컴포넌트의 실행 시점이 중요하다.
- 값 커네이선스
상호 연관된 다수의 값들을 함께 변경할 때 발생한다.
사각형의 한 꼭지점만 변경되는 경우
- 식별 커네이선스
여러 컴포넌트가 동일한 엔티티를 참조할 때 발생한다.
커네이선스 속성
커네이선스는 아키텍트와 개발자에게 유용한 분석도구이다.
다음 프로퍼티를 잘 활용하면 개발자에게 도움이 된다.
- 강도
아키텍트는 개발자가 어떤 유형의 커네이선스를 얼마나 쉽게 리팩터링할 수 있는지에 따라 커네이선스 강도를 결정한다.
아키텍트와 개발자는 더 나은 유형의 커네이선스를 리팩터링해서 코드베이스의 커플링 특성을 개선할 수 있다.
- 지역성
커네이선스의 지역성은 코드베이스의 모듈들이 서로 얼마나 가까이 있는가, 입니다.
근접한 코드는 보통 더 분리된 코드보다 높은 형태의 커네이선스를 가진다.
즉, 모듈을 떨어뜨렸을 때 커플링이 형편없는 형태의 커네이선스는 모듈을 서로 가까이 붙여 놓는 식으로 개선할 수 있다.
개발자는 강도와 지역성을 함께 고민해야 한다.
동일한 모듈에서 더 강한 형태의 커네이선스가 발견된다면 그와 동일한 커네이선스가 널리 흩어져 있는 것보다 코드 스멜이 더하다는 증거다.
- 정도
커네이선스 정도는 커네이선스가 미치는 영향의 규모에 관한 것이다.
이 값이 작을수록 코드베이스 입장에서는 바람직하다.
모듈이 몇 개 안된다면 동적 커네이선스가 노아도 별로 해롭지 않지만, 일반적으로 코드베이스는 점점 커지기 마련이니 사소한 문제도 점점 더 악화될 것이다.
페이지-존스가 제안한 커네이선스를 활용해 시스템의 모듈성을 개선하는 세 가지 방법이다.
- 시스템을 캡슐화한 요소들로 잘게 나누어 전체 커네이선스를 최소화한다.
- 캡슐화 경계를 벗어나는 나머지 커네이선스를 모조리 최소화한다.
- 캡슐화 경계 내부에서 커네이선스를 최대화한다.
정도의 규칙: 강한 형태의 커네이선스를 보다 약한 형태의 커네이선스로 전환하라
지역성의 규칙: 소프트웨어 엘리먼트간의 거리가 멀어질수록 보다 약한 형태의 커네이선스를 활용해라
3.2.6 커플링과 커네이선스 메트릭을 통합
지금까지 우리는 시기와 목표가 상이한 커플링과 커네이선스를 이야기했다.
하지만 아키텍트 관점에서 이 두 가지 뷰가 서로 중첩된다.
3.3 모듈에서 컴포넌트로
이 책에서는 연관된 코드의 묶음을 모듈이라고 일반 용어로 표현하지만 대부분의 프랫폼은 컴포넌트로 표현한다.
느낀점
모듈성에 대한 내용과 아키텍트에 시점으로 잘 설명되었지만….. 어려운 수학내용이 있어서 읽기 힘들었따..
논의사항
실제로 회사에서 작업을 할 때 메트릭을 다 시각화하는지… 궁금합니다..!
4. 아키텍처 특성 정의
어떤 문제를 소프트웨어로 해결하려면 아키텍트는 먼저 시스팀 요구사항을 취합하고 그것을 구현하 데 다양한 기술을 소프트웨어 개발 프로세스에 따라 정한다.
그러나 이밖에도 아키텍트는 소프트웨어 솔루션을 설계할 때 많은 부분을 고려해야 한다.
아키텍트는 개발팀과 함께 도메인 또는 비즈니스 요구사항을 정의할 수 있지만, 주로 소프트웨어로 처리할 일 중 도메인 기능과 직접적인 관련이 없는 모든 것들
즉 아키텍처 특성을 정의, 발견, 분석하는 일을 한다.
아키텍처 특성은 다음 세 가지 기준을 충족한다.
- 비도메인 설계 고려 사항을 명시한다.
- 설계의 구조적 측면에 영향을 미친다.
- 애플리케이션 성공에 (절대적으로) 중요하다.
비도메인 설계 고려 사항을 명시한다.
애플리케이션 설계 시 애플리케이션으로 처리할 일은 구체적인 요구사항으로 정리한다.
아키텍처 특성은 이 요구사항을 구현하는 방법, 어떤 선택을 하게 된 이유와 관련된 운영/설계 기준을 명시한다.
설계의 구조적 측면에 영향을 미친다.
프로젝트 담당 아키텍트가 아키텍처 특성을 기술하는 주된 이유는 ‘이 아키텍처 특성은 어떤 특별한 구조적 요소를 고려해야 하는가?’하는 설계 고려 사항 때문이다.
애플리케이션 성공에 (절대적으로) 중요하다.
애플리케이션이 무수히 많은 아키텍처 특성을 전부 다 지원할 수 있겠지만, 사실 그러면 안된다.
지원하는 아키텍처 특성을 한 가지만 늘려도 그만큼 설계 복잡도는 가중되니까요. 가급적 아키텍처 특성을 적게 선정하는 일도 아키텍트의 중요한 책무이다.
우리는 아키텍처 특성을 명시적특성과 암묵적특성으로 분류합니다.
암묵적 특성은 요구사항 정의서에는 거의 안나오지만 프로젝트 성공을 위해 꼭 필요한 특성들이다.
명시적 아키텍처 특성은 요구사항 정의서나 다른 지침서에 기재된다.
4.1 아키텍처 특성 목록
아키텍처 특성은 모듈성 같은 저수준 코드의 특성부터 확장성, 탄력성 같은 복잡한 운영 문제까지 소프트웨어 시스템의 넓은 범위에 골고루 존재한다.
규모와 범위는 방대하지만 아키텍트는 보통 아키텍처 특성을 넓은 범주로 나눈다.
4.1.1 운영 아키텍처 특성
운영 아키텍처 특성은 성능, 확장성, 탄력성, 가용성, 신뢰성 등의 능력을 말한다.
용어 | 정의 |
---|---|
가용성 | 시스템이 얼마나 오랫동안 사용 가능해야 하나? |
연속성 | 재해복구능력 |
성능 | 스트레스 테스트, 피크 분석, 기능의 사용 빈도 분석, 필요 용량, 응답 시간 |
복구성 | 비즈니스 연속성 요구사항 |
신뢰성/안전 | 시스템에 페일 세이프가 필요한가? |
견고성 | 프로그램 실행 중 인터넷 접속 끊김, 정전, 하드웨어 등 에러 및 경계조건을 감당하는 능력 |
확장성 | 유저 수, 요청 수가 늘어나도 시스템이 그에 맞는 성능을 발휘 하는 능력 |
운영 아키텍처 특성은 운영 및 데브옵스와 많은 부분에서 중첩되며, 많은 소프트웨어 프로젝트에서 이런 관심사는 교차점을 형성한다.
4.1.2 구조 아키텍처 특성
아키텍처는 코드 구조에도 심혈을 기울여야 하며, 일반적으로 우수한 모듈성, 컴포넌트 간 커플링 제어, 가독성 높은 코드, 그 밖의 내부 품질 평가 등 코드 품질 문제를 전담합니다.
용어 | 정의 |
---|---|
설정성 | 최종 유저가 소프트웨어 설정을 쉽게 바꿀 수 있는가? |
신장성 | 새로운 기능을 삽입하는 일의 중요성 |
설치성 | 필요한 모든 플랫폼에 시스템을 얼마나 쉽게 설치할 수 있는가? |
활용성/재사용 | 공통 컴포넌트를 여러 제품에서 활용할 수 있나? |
지역성 | 데이터를 입력/조회하는 화면에서 다국어가 지원되는가? |
유지보수성 | 시스템을 얼마나 쉽게 변경/개선할 수 있나? |
이식성 | 하나 이상의 플랫폼에서 시스템을 실행할 수 있나? |
지원성 | 애플리케이션은 어느 정도의 기술 지원을 필요로 하나? |
업그레이드성 | 이 애플리케이션의 구 버전을 새 버전으로 쉽고 빠르게 업그레이드 할 수 있는가? |
4.1.3 아키텍처 공통 특성
쉽게 분류할 수 있는 범주에 속하는 아키텍처 특성들도 있는 반면, 중요한 설계 제약조건과 고려사항은 대부분 따로 분류하기 어려운 경우가 많다.
용어 | 정의 |
---|---|
접근성 | 색맹,청각 장애인 등 모든 유저가 접근하는 데 불편함이 없나? |
보관성 | 데이터를 따로 아카이빙해야 하나, 아니면 일정 시간 경과 후 삭제해야 하나 |
인증 | 유저가 본인이 맞다는 것을 증명하기 위해 필요한 보안 요구사항 |
인가 | 유저가 애플리케이션에서 정해진 기능만 사용할 수 있도록 강제하는 보안 요구사항 |
합법성 | 시스템 운영상 법적 제약조건이 있는가? |
프라이버시 | 회사 내부 임직원의 트랜잭션을 외부에 드러내지 않는 기능 |
보안 | 데이터를 암호화한 후 데이터베이스에 보관해야 하나? |
사용성/성취성 | 유저가 애플리케이션을 이용하여 원하는 목적을 달성하기 위해 필요한 교육/훈련 수준 |
아키텍처 특성은 어떻게 나열해도 불완전한 목록이 될 수밖에 없고, 소프트웨어마다 고유한 팩터를 바탕으로 중요한 아키텍처 특성이 도출될 수도 있다.
실제로 ISO에서 정의한 목록을 봐도 비슷하거나 목록자체가 불완전한 모습을 볼 수 있다.
4.2 트레이드오프 및 나쁜 것 중에서 제일 나은 아키텍처
지금까지 열거한 아키텍처 특성들은 여러 가지 이유로 일부만 애플리케이션에서 지원 가능하다.
- 지원되는 특성마다 설계 노력이 필요하고 구조적으로도 지원되어야 한다.
- 각 아키텍처 특성이 다른 특성에 영향을 미치는 경우가 많다는 사실이 더 큰 문제이다.
아키텍트가 설계하기로 결정한 아키텍처 특성 하나하나가 전체 설계를 복잡하게 만들 가능성을 폼고 있다.
따라서 시스템을 설계하며 모든 아키텍처 특성을 빠짐없이 최상으로 반영하기란 불가능에 가깝고 아키텍트가 내린 결정은 상충되는 여러 문제들이 뒤얽힌 트레이드오프로 귀결되는 경우가 많다.
“최고의 아키텍처를 고집하지 말고 나쁜 것 중에서 제일 나은 아키텍처를 선택해라”
아키텍처 특성을 너무 욕심내면 모든 비즈니스 문제를 해결하려고 시도하는 일반적인 솔루션이 되어버린다.
그러나 그런 아키텍처는 설계하기가 대단히 까다롭다.
아키텍트가 좋은 아키텍처를 설계하기 위해선 꾸준하게 설계를 해보는 것이 좋다.
반복의 가치는 애자일 소프트웨어 개발에서도 가장 중요한 교훈중 하나로 아키텍처뿐만 아니라 모든 레벨의 소프트웨어 개발에서도 적용된다.
느낀점
처음 아키텍처 특성을 읽어가며 적고 나서 모든 걸 반영하고 싶어하는 욕심 그리고 정답에 가까워지고 싶어하는 생각을 했는데..
트레이드오프, 불가능에 가깝다는 이야기..
항상 최악이라는 것이 아니라 그 때 선택할 수 있는 최선의 아키텍처를 설계하기 위해서 항상 노력하고 다양한 방면으로 기술을 쌓아야 한다..
논의사항
다들 경험해보신 적 있으신지 모르겠지만, 아키텍처뿐만 아니라 뭔가 정답 코드가 있을 것 같고, 개발에서 제대로된 패스나 좋은 구조,,?를 욕심내고 그런 것에 대한 강박을 가진 적이 있는데.. 다들 그런 생각에서 벗어나신 경험이나 계기가 궁금합니다.
5. 아키텍처 특성 식별
아키텍처를 구상하거나 기존 아키텍처의 타당성을 검증할 때 제일 먼저 해야하는 이은 아키텍처 특성을 식별하는 일 이다.
아키텍처 특성을 정확하게 식별하기 위해선 해당 도메인을 잘 알고 있어야 하며, 도메인 이해관계자들과 협력하여 도메인 관점에서 중요한 것들을 결정해야 한다.
아키텍트는 적어도 도메인 관심사, 요구사항, 암묵적 도메인 지식 이렇게 세가지 출저에서 아키텍처 특성을 밝혀낸다.
5.1 도메인 관심사에서 아키텍처 특성 도출
도메인 이해관계자와 협력해서 주요 아키텍처 특성을 정의하는 한 가지 팁은, 최종 목록을 가능한 한 짧게 하는 것이다.
아키텍처에서 가장 흔한 실수, 안티패턴은 모든 아키텍처 특성을 지원하는 제네릭 아키텍처를 설계하려 하는 것이다.
아키텍처 특성 하나하나가 시스템의 설계를 복잡하게 만드는 요인이기 때문에 너무 많은 아키텍처 특성을 수용하면 아키텍트, 개발자가 의도했던 문제 영역의 해결을 시도하기도 전에 아키텍처가 너무 복잡해져버린다.
따라서 아키텍처 특성의 개수에 연연하지 말고 가급적 설계를 단순화하는게 좋다.
아키텍트와 도메인 이해관계자는 애초에 다른 사람이기 때문에 의견과 시점이 다를 수 밖에 없다.
가장 중요한 특성을 순위를 매겨 진행하게 되면 마찰과 갈등이 생겨서 만장일치로 돌아가는 경우가 적다.
따라서 최종 목록을 뽑은 뒤 각각 3개씩 뽑아서 좀 더 중요한 특성이 뭔지 고민해보는 시간을 가지는 것이 좋다.
아키텍처의 특성은 핵심 도메인 이해관계자들의 의견을 듣고 도메인 관점에서 무엇이 중요한지 의견을 교환하면서 정리 된다.
문제가 없어보이지만 도메인 이해관계자들과 아키텍트의 언어는 다르다.
아키텍트는 확장성, 상호운용성, 내고장성, 학습성, 가용성을 운운하지만 이해관계자들은 인수병합, 고객 만족, 출시 시점등의 경쟁우위를 논한다.
이러한 문제를 해결하기 위해 저자는 도메인 관심사를 아키텍처 특성으로 옮겨 적은 표를 제공한다.
도메인 관심사 | 아키텍처 특성 |
---|---|
인수 합병 | 상호운용성, 확장성, 적응성, 신장성 |
출시 시기 | 민첩성, 시험성, 배포성 |
유저 만족 | 성능, 가용성, 내고장성, 시험성, 배포성, 민첩성, 보안 |
경쟁 우위 | 민첩성, 시험성, 배포성, 확장성, 가용성, 내고장성 |
시간 및 예산 | 단순성, 실행성 |
5.2 요구사항에서 아키텍처 특성 도출
요구사항 정의서에 명시된 문장에서 도출한 아키텍처 특성도 있다.
예상 유저수와 그에 따른 확장 문제는 보통 도메인 관심사에서 빠지지 않는 단골 손님이다..
아키텍트가 알고 있는 도메인 지식에서 도출되는 특성들도 있는데, 이것이 아키텍트가 도메인 지식을 갖고 있으면 이로운 이유이다.
초보 아키텍트가 도메인에 관한 설명을 보고 아키텍처 특성을 도출하는 연습을 할 수 있도록 아키텍처 카타를 고안했다.
5.3 사례 연구: 실리콘 샌드위치
실리콘 샌드위치 카타를 예로 들어 아키텍트가 요구사항을 바탕으로 아키텍처 특성을 도출하는 방법을 알아보자
- 설명
- 실리콘 샌드위치는 전국 가맹점을 보유한 샌드위치 브랜드로 온라인 주문 시스템을 구축하려 한다.
- 유저
- 앞으로 수천명, 어쩌면 수백만 명에 달할 지도 모른다.
- 요구 사항
- 유저가 주문을 하면 샌드위치를 픽업하러 갈 시간 및 상점까지 가는 경로를 전달받는다(교통 정보가 포함된 여러 외부 지도 서비스와 연계는 필수).
- 배달 서비스가 가능한 지점은 기사를 보내 샌드위치를 유저에게 배달한다.
- 모바일 기기에서도 이용 가능하다.
- 전국 어느 지점이나 이용 가능한 프로모션/스페셜 행사를 제공한다.
- 특정 지점에서만 이용 가능한 로컬 프로모션/스페셜 행사를 제공한다.
- 온라인 결제, 대면 결제. 배송 시 결제 등 다양한 결제 옵션을 제공한다.
- 부가 콘텍스트
- 샌드위치 지점은 가맹점이므로 소유자가 다 다르다.
- 모회사는 머지않아 해외 시장도 진출할 계획이다.
- 이 회사는 값싼 인력을 고용해 이윤을 최대화하는 것이 목표다.
요구사항 하나하나가 여러 아키텍처 특성과 연관이 있을 수 있고 없을 수 있다.
여기서 아키텍트는 도메인 요구사항을 충족하는 전체 시스템을 코드 레벨로 설계하는 것이 아니라, 설계, 특히 구조와 관련이 있거나 영향을 미치는 것들을 찾아내는 것이다.
먼저 아키텍처 특성이 될 만한 것과 암묵적인 것으로 분류한다.
5.3.1 명시적 특성
명시적 아키텍처 트성은 필요한 설계의 일부로서 요구사항 정의서에 기술된다.
아키텍트가 가장 먼저 봐야할 부분은 유저 수
다.
지금은 수천 명 정도라고 생각했지만 나중에 수백만명에 이를 수 있다고 한다.
따라서 확장성, 즉 유의미한 성능 저하 없이 다수의 동시 유저를 처리하는 능력이 무엇보다 중요한 아키텍처 특성으로 보인다.
순간적으로 폭증하는 유저 요청을 처리하려면 탄력성도 필요하다.
확장성과 탄력성은 한몸처럼 나타날 때도 많지만 제약조건은 각각 다르다.
확장성은 좋지만 탄력성은 좋지 못한 시스템도 있다.
호텔 예약시스템
그럼 샌드위치 시스템에선..? 점심시간에 몰리는 유저들을 생각하여 확장성도 고려해야 한다..
- 유저가 주문을 하면 샌드위치를 픽업하러 갈 시간 및 상점까지 가는 경로를 전달받는다(교통 정보가 포함된 여러 외부 지도 서비스와 연계는 필수).
외부 지도 서비스는 연계 지점에 해당하므로 신뢰성과 같은 특성에 영향을 미칠 수 있다.
서드파티 시스템에 의존하는 시스템은 서드파티 시스템 호출이 실패할 경우 전체 시스템 안정성이 타격을 입는다.
그러나 아키텍트는 과도하게 특성을 설정하지 않도록 유의할 필요도 있다.
외부 지도 서비스가 다운되면 실리콘 샌드위치 사이트 전체가 중단될까 교통정보가 빠진 덜 쓸모 있는 서비스가 제공될까?
- 배달 서비스가 가능한 지점은 기사를 보내 샌드위치를 유저에게 배달한다.
별다른 아키텍처 특성이 필요하지 않다.
- 모바일 기기에서도 이용 가능하다.
이 요구사항은 애플리케이션을 설계할 때 이식성이 좋은 웹 애플리케이션과 다양한 네이티브 웹 애플리케이션중 어느 쪽으로 개발할 것인가, 방향성을 결정하는 것처럼 큰 비중을 차지한다.
예산, 인력을 고민하여 아키텍처 특성을 정의할 수 있지만 아키텍트는 결코 혼자 움직여선 안 되며, UX 설계자, 도메인 담당자, 기타 도메인 이해관계자들과 충분한 협의를 거치는 것이 좋다.
- 전국 어느 지점이나 이용 가능한 프로모션/스페셜 행사를 제공한다.
- 특정 지점에서만 이용 가능한 로컬 프로모션/스페셜 행사를 제공한다.
4,5번은 프로모션과 스페셜 행사에 관한 커스터마이징 가능 여부에 관한 요구사항이다.
1번 요구사항은 유저 주소에 맞는 교통정보의 커스터마이징을 의미하므로 아키텍트는 이 세가지 요구사항을 토대로 맞춤성을 도출할 수 있다.
- 온라인 결제, 대면 결제, 배송 시 결제 등 다양한 결제 옵션을 제공한다.
온라인 결제는 보안이 당연하게 필요하지만 이 요구사항만 봐서는 어느정도의 보안이 필요한지 잘 모르겠다..
- 샌드위치 지점은 가맹점이므로 소유자가 다 다르다.
이 요구사항은 아키텍처 비용에 제약을 가한다. 아키텍트는 단순하거나 기능이 조금 빠진 아키텍처로도 충분한지 타당서을 미리 확인해야 한다.
- 모회사는 머지않아 해외 시장도 진출할 계획이다.
이 요구사항은 아키텍처의 국제화를 고려해야 한다.
- 이 회사는 값싼 인력을 고용해 이윤을 최대화하는 것이 목표다.
중요하지 않지만 아키텍처 특성보다 설계와 더 깊은 연관이 있다.
요구사항 정의서에서 도출한 세 번째 아키텍처 특성은 성능이다.
5.3.2 암묵적 특성
요구사항 정의서에는 따로 없는 아키텍처 특성도 있지만 이들은 각각 중요한 설계 요소가 된다.
가용성은 시스템에서 마땅히 지원되어야 할 암묵적인 아키텍처 특성으로, 유저는 샌드위치 사이트에 접속할 수 있어야 한다.
마찬가지로 사이트를 문젱없이 사용하려면 신뢰성 역시 반드시 필요하다..
보안은 모든 시스템에 공통적인 암묵적 특성이다.
아키텍처 특성은 서로 연관되어 움직이므로 중요도에 따라 우선순위는 매우 달라질 수 있다.
실리콘 샌드위치의 마지막 아키텍처 특성으로는 요구사항 곳곳에 해당되는 맞춤성을 꼽을 수 있다.
레시피, 로컬판매, 약도 등 문제 영역의 여러 부분을 유저의 의도에 맞게 다시 정의해야 하므로 커스터마이징이 원활하게 지원되는 아키텍처가 필요하다.
설계 대 아키텍처, 그리고 트레이드오프
실리콘 샌드위치 카타에서 맞춤성을 시스템의 일부로 식별하는 아키텍트도 있겠지만, 문제는 이것이 아키텍처냐 설계냐,는 것이다. 아키텍처는 구조적 컴포넌트를 나타내지만, 설계는 아키텍처 내부에 속한다.
아키텍트는 애플리케이션 스스로 커스텀 로직을 지원하도록 맞춤성을 아키텍처 구조 설계에 반영하지 않을 수 있다
개발자는 어떤 방법을 쓰더라도 기능을 구현할 수 있으므로 아키텍트는 아키텍처 특성을 정확하게 발견하려고 너무 스트레스를 받을 필요는 없다.
물론 중요한 구조적 요소를 정확하게 식별하면 단순 우아하게 설계가 가능하다.
아키텍처에서 최고의 설계는 없다. 오직 나쁜 것중에서 제일 나은 트레이드오프들만 있을 뿐
느낀점
아키텍트의 역할과 설계의 차이점이 조금 헷갈렸는데 설계보다는 좀 더 인지적인 능력이 많이 필요한 것 같다.
책에서도 강조하는 커뮤니케이션적인 능력이 있어야 다른 파트와 소통하고 협업할 수 있을 것 같다.
논의사항
6. 아키텍처 특성의 측정 및 거버넌스
아키텍트는 소프트웨어 프로젝트의 거의 전부에서 엄처나게 다양한 아키텍츠 특성을 다루는 사람이다
이 장에선 일반적인 아키텍처 특성을 구체적으로 정의하고 거버넌스 메커니즘을 구축하는 방법을 집중적으로 살펴본다.
6.1 아키텍처 특성 측정
아키텍처 특성을 정의할 때에는 흔히 다음과 같은 문제들이 발생한다.
- 물리학이 아니다.
- 아키텍처 특성은 대부분 모호하다.
- 정의가 너무 다양하다.
- 성능 같은 중요한 특성에 대한 정의가 같은 조직에서도 부서마다 일치하지 않아 작업자가 모두 정의를 통일하기 이전에 원활하게 소통하기 어렵다.
- 너무 복잡하다.
- 바람직한 아키텍처 특성은 대부분 더 작은 여러 특성들로 구성되기 때문에 복합적이다.
이 세가지 문제는 사실 아키텍처 특성을 객관적으로 정의하면 모두 해결된다.
따라서 팀, 조직단위에서 아키텍처 특성을 명확하게 한다면 공통의 아키텍처언어를 확립할 수 있다.
6.1.1 운영적 특성
아키텍처 특성은 성능, 확장성처럼 비교적 정확하게 측정할 수 있는 것도 많지만, 팀 목표에 따라 그에 따른 해석은 미묘하게 갈릴 때가 많다.
성능의 여러 가지 맛
많은 아키텍처 특성이 미묘한 의미를 갖고 있다.
성능 또한 그 중 하나이다.
대부분의 프로젝트는 일반적인 성능을 살표보지만, 아키텍트와 데브옵스 엔지니어는 다른 시각으로 성능을 분석한다.
수준 높은 팀은 달성하기 어려운 성능 수치를 정하는 대신, 통계 분석 결과로 얻은 나름대로의 정의에 기반한다.
엔지니어가 통계모델을 수립하여 해당 모델의 예측이 빗나갔다면, 그 모델이 부정확하거나 잘못된 부분이 있다는 것인데 이 내용은 팀에서 알고싶어하고 도움이 되는 정보이다..
6.1.2 구조적 측정
성능처럼 목표치가 확실하지 않은 메트릭도 있다.
잘 정의된 모듈성처럼 내부 구조에 관한 특성들도 그렇다..
아직 내부 코드 품질에 대한 종합적인 메트릭은 없지만 아키텍트는 다른 메트릭과 공통 도구를 이용해서 코드 구조에 관한 중요한 부분을 들여다 볼 수 있다.
코드의 순환 복잡돌는 메트릭을 통해서 명쾌하게 측정할 수 있다.
아키텍트와 개발자 모두 너무 복잡한 코드는 코드 스멜이라는 말에 공감한다.
그런 코드들은 모듈성, 시험성, 배포성 등 거의 모든 바람직한 코드 베이스 특성을 저해하는 요소이다.
6.1.3 프로세스 측정
소프트웨어 개발 프로세스와 교차하는 아키텍처 특성도 있다.
민첩성은 마람직한 특성으로 보일 때가 많은데, 이는 시험성, 배포성등의 특성으로 나눌 수 있는 복합적인 아키텍처 특성이다.
6.2 거버넌스와 피트니스 함수
거버넌스란 조직이 목표를 달성하기 위해 행동하는 방식을 정의하는 것이다.
피트니스 함수란 거버넌스의 일부로서, 조직이 목표를 달성하기 위해 행동하는 방식을 정의하는 것이다.
아키텍트가 아키텍처 특성을 확정 후 우선순위를 정하면 개발자들이 이 우선순위를 잘 지킬 거라 어떻게 확신할 수 있을까..?
6.2.1 아키텍처 특성 관리
거버넌스는 Kubernan(이글다)라는 그리스어에서 유래된 말이다.
거버넌스는 아키텍트가 담당하는 중요한 업무로 모든 소프트웨어 개발 프로세스를 포괄한다.
예를 들어 조직 내부에서 소프트웨어 품질 모장 업무는 아키텍처 범주 안에 속하므로 아키텍처 거버넌스 항목이다.
요즘에는 다양한 솔루션이 많이 등장하면서 익스트림 프로그래밍과 같은 소프트웨어 프로젝트 자동화 움직임은 지속적으로 발전해왔으며 피트니스 함수의 개념이 등장하였다.
6.2.2 피트니스 함수
결과가 얼마나 목표에 근접했는지를 나타내는 목표 함수가 바로 피트니스 함수이다.
아키텍처 피트니스 함수
어떤 아키텍처 특성의 객관적인 무결성을 평가하는 모든 메커니즘
피트니스 함수는 아키텍트가 그냥 다운로드 받아 사용하는 새로운 프레임 워크가 아니라 수 많은 기존 도구들을 바라보는 새로운 시각이다.
아키텍처 특성을 검증하는 기법은 그 특성만큼이나 다양하다.
피트니스 함수는 사용하는 방법에 따라 메트릭, 모니터, 단위 테스트 라이브러리, 카오스 엔지니어링등 기존의 많은 메커니즘과 중첩되는 부분이 있다.
순환 의존성
모듈성은 대부분의 아키텍트가 관심을 기울이는 암묵적인 아키텍처 특성이다.
모듈성이 제대로 유지되지 못하면 코드베이스 구조에 해를 끼치므로 우선 순위를 높게 두어 관리할 수 밖에 없다..
느낀점
거버넌스와 피트니스 함수는 좋은 코드 나쁜 코드에서도 본 것 같은데 여기서 의미를 제대로 파악한 것 같다..
실리콘 밸리의 팀장들과 같이 매니징, 관리 능력도 많이 요구되는 것 같다
논의사항
7. 아키텍처 특성 범위
소프트웨어 아키텍처 세계에서는 전통적으로 아키텍처 특성의 범위를 시스템 레벨에 두는 것을 당연시했다.
10년전 모놀리식에서 마이크로서비스 등의 아키텍처 스타일이 가능해지면서 아키텍처 특성의 범위는 상당히 좁아졌다.
소프트웨어 개발 생태계가 무서운 속도로 진화하면서 당연시 여겼던 공식들이 퇴화하고 있다.
아키텍트는 운영 아키텍처 특성을 따져보고 아키텍처 특성에 영향을 미치는 코드베이스 외부의 컴포넌트를 잘 살펴봐야 한다.
그래서 이런 종류의 의존성을 측정하기 위해 아키텍처 퀀텀
이라는 용어를 정의했다.
이 용어를 이해하기 위해선 커네이선스라는 핵심 메트릭을 알아야 한다.
7.1 커네이선스
두 컴포넌트 중 한쪽이 변경될 경우 다른 쪽도 변경해야 전체 시스템의 정합성이 맞는다면 이 들은 커네이선스를 갖고 있는 것이다.
저번에도 생각했지만 의존성 역전의 원칙과 비슷한 결인지,, 디커플링과 비슷한 개념으로 소개된 적 있었다.
예를 들어 마이크로 서비스 아키텍처의 두 서비스가 address라는 동일한 클래스를 공유한다면 두 서비스는 서로 정적인 커네이선스를 가진다고 볼 수 있다.
다시 말해 address라는 공유 클래스를 변경하면 두 서비스 모두 변경해야 한다.
동적 커네이선스는 동기, 비동기 두 종류가 있다..
분산 서비스끼리 동기 호출을 하면 호출부는 피호출부의 응답을 기다려야 하는 반면, 이벤트 기반 아키텍처의 비동기 호출은 파이어 앤드 포켓 방식이므로 운영 아키텍처에서 두 서비스는 개별적으로 작동시킬 수 있다.
7.2 아키텍처 퀀텀과 세분도
소프트웨어를 서로 엮는 것은 컴포넌트 레벨의 커플링만이 아니다.
많은 비즈니스 개념이 의미상 여러 시스템 파트를 엮어 기능적으로 응집되어 있다..
성공적으로 소프트웨어를 설계, 분석, 발전시키기 위헤서 개발자는 문제가 될 만한 지점을 모두 살펴봐야 한다.
- 아키텍처 퀀텀
- 높은 기능 응집도와 동기적 커네이선스를 가진, 독립적으로 배포 가능한 아티팩트
- 독립적으로 배포 가능
- 아키텍처 퀀텀은 아키텍처의 다른 파트와 독립적으로 작동되는 모든 필수 컴포넌트를 포함한다.
- 높은 기능 응집도
- 응집도는 컴포넌트 설계에 따라 구현된 코드가 얼마나 목적에 맞게 통합되어 있는지를 나타낸다.
- 동기적 커네이선스
- 동기적 커네이선스는 아키텍처 퀀텀을 형성하는 애플리케이션 콘텍스트 내부 또는 분산 서비스간의 동기 호출을 의미한다.
아키텍처 퀀텀 개념은 아키텍처 특성의 새로운 범위를 제시한다. 현대 시스템에서 아키텍트는 시스템 레벨보다는 퀀텀 레벨의 아키텍처 특성을 정의한다.
느낀점
커네이선스에 대해서 조금 어려웠는데 다시 한번 다루니까 개념이 확실히 잡힌 느낌..!
논의사항
8. 컴포넌트 기반 사고
3장에서는 모듈을 연관된 코드의 묶음이라고 했지만, 아키텍트는 보통 모듈을 불리적으로 구현한 컴포넌트로 생각한다.
개발자는 자신의 개발 플랫폼에 따라 여러 가지 방법으로 모듈을 물리적으로 패키징한다.
이렇게 모듈을 물리적으로 패키징한 것을 컴포넌트라고 하며 자바(jar), 닷넷(dll)처럼 대부분의 언어들이 지원하는 기능이다.
8.1 컴포넌트 범위
개발자는 컴포넌트 개념을 다양한 펙터에 세분화하는 것이 유용하다고 생각한다.
컴포넌트는 아티팩트를 한데 묶어 필요시 중첩시켜 계층화하는, 언어에 특정한 메커니즘을 제공한다.
가장 단순한 컴포넌트는 클래스보다 한 단계 높은 수준의 모듈로 코드를 래핑한 것이다..!
이 단순한 래퍼를 보통 라이브러리라고 한다.
라이브러리는 대개 호출부 코드와 동일한 메모리 주소에서 실행되며 해당 언어의 함수 호출 메커니즘을 사용한다.
그리고 일반적으로 라이브러리는 컴파일 타임에 의존한다.
아키텍트가 반드시 컴포넌트를 사용하는 것은 아니며 컴포넌트는 언어가 제공하는 저수준이 아닌 더 높은 고 수준에서 모듈성을 가지는 것이 더 유용할 때가 많다.
8.2 아키텍트 역할
아키텍트는 아키텍처 내부의 컴포넌트를 정의, 개선, 관리, 통제하는 일을 한다.
소프트웨어 아키텍트는 4장에서 열거한 아키텍처 특성과 소프트웨어 시스템의 요구사항을 종합하여 비즈니스 분석가, 분야별 전문가, 개발자, QA 엔지니어, 운영자, 엔터프라이즈 아키텍트와 함께 소프트웨어 초기 설계를 한다.
아키텍트는 개발 프로세스의 영향을 거의 받지 않지만 예외로 애자일 소프트웨어 개발 방법론의 다양한 분야를 개척한 엔지니어링 프랙트시를 필요로 한다.
특히 CI/CD, 거버넌스 분야가 글허다..
새 프로젝트를 시작한 아키텍트는 무엇보다 먼저 컴포넌트를 식별해야 하나, 그 전에 아키텍처를 분할하는 방법을 반드시 이해해야 한다.
8.2.1 아키텍처 분할
소프트웨어 아키텍처 제1법칙에 따르면 소프트웨어는 만사가 다 트레이드오프이다.
주어진 아키텍처에서 컴포넌트를 만드는 방법도 마찬가지이다.
컴포넌트는 일반적인 적재 메커니즘을 의미하므로 아키텍트는 재량껏 어떤 유형의 분할도 할 수있다..
콘웨이의 법칙: 시스템을 설계하는 조직은 그 조직의 소통 구조를 그대로 옮겨 놓은 듯한 설계도를 그릴 수밖에 없다.
8.3 개발자 역할
개발자는 아키텍트의 공동 설계한 컴포넌트를 바탕으로 클래스, 함수, 서브컴포넌트로 더 잘게 나눈다.
일반적으로 클래스, 함수 설계는 아키텍트, 기술 리더, 개발자의 공동 책임이지만 대부분 개발자가 담당한다.
개발자는 아키텍트가 설계한 컴포넌트가 최종판이라고 생각하면 안 된다.
모든 소프트웨어 설계는 이터레이션을 거쳐 점점 다듬어진다.
초기 설계는 일단 초안으로 보고 차후 구현을 하며 상세한 것들을 밝히고 하나씩 개선을 하면 된다.
8.4 컴포넌트 식별 흐름
아키텍처는 이런 주기를 반복하면서 점점 구체화된다.
따라서 아키텍처는 수정, 변형을 두려워 해서는 안된다…!
8.4.1 초기 컴포넌트 식별
아키텍트는 소프트웨어 프로젝트의 소스 코드가 생기기 전에 적용할 최상위 분할의 유형에 따라 최상위 컴포넌트를 어디서부터 시작할지 결정해야 한다.
그 밖에도 아키텍트는 원하는 컴포넌트를 자유롭게 구성하면서 어느 기능을 어디에 둘지 도메인 기능을 매핑한다.
초기 식별한 컴포넌트들만으로 제대로 된 설계가 나올 가능성은 거의 없으니 아키텍트는 컴포넌트 설계를 이터레이션하면서 조금씩 개선해야 한다.
8.4.2 요구사항을 컴포넌트에 할당
초기 컴포넌트를 식별한 후, 아키텍트는 컴포넌트에 요구사항을 대입해서 잘 맞는지 확인한다.
이 과정에서 컴포넌트를 새로 만들거나 기존 컴포넌트를 통합하고 하는 일이 너무 많은 컴포넌트를 분해할 수 있다.
8.4.3 역할 및 책임 분석
컴포넌트에 스토리를 대입할 때 아키텍트는 요구사항을 파악하는 단계에서 밝혀진 역할과 책임도 살펴보고 세분도가 적합한지 확인한다.
8.4.4 아키텍처 특성 분석
컴포넌트에 요구사항을 대입할 때 아키텍트는 앞서 식별한 아키텍처 특성들이 컴포넌트 분할 및 세분도에 어떤 영향을 미치는지 살펴봐야 한다.
8.4.5 컴포넌트 재구성
소프트웨어 설계에서 피드백은 항상 중요하다.
아키텍트는 개발자와 지속적으로 컴포넌트 설계를 반복해야 한다.
8.5 컴포넌트 세분도
컴포넌트에서 가장 적당한 세분도를 찾는 것은 아키텍트의 가장 어려운 작업 중 하나이다.
컴포넌트를 너무 잘게 나누어 설계하면 컴포넌트 간 통신이 너무 많아지고, 그렇다고 너무 크면 커플링이 증가해 배포, 테스트가 어려워 진다.
8.6 컴포넌트 설계
컴포넌트 설계에 있어서 ‘왕도’는 없다..
팀과 조직에서 사용하는 소프트웨어 개발 프로세스와 맞물려 다양한 기술과 트레이드오프가 있겠지만, 아키텍트는 아키텍처를 설계하면서 요구사항을 접수하고 애플리케이션을 구성할 굵직굵직한 구성 요소를 그려봐야 한다.
8.6.1 컴포넌트 발견
아키텍트는 개발자, 비즈니스 분석가, 도메인 전문가와 협력해서 시스템에 관한 일반적인 지식과 시스템을 어떻게 분할할지 결정하고 그에 따라 초기 컴포넌트 설계를 한다.
엔티티 함정
컴포넌트를 확정하는 문제에 정답은 없지만, 엔티티 함정 안티 패턴은 자주 나오니 조심해야 한다.
액터/액션 접근법
액터/액션 접근법은 아키텍트가 요구사항을 컴포넌트에 매핑할 때 즐겨 쓰는 방법이다.
아키텍트는 애플리케이션에서 뭔가 일을 하는 액터와 그들이 수행하는 액션을 식별하고 시스템의 대표적인 유저와 이들이 시스템에서 어떤 종류의 일을 하는지 찾아내는 기법이다.
이벤트 스토밍
이벤트 스토밍은 도메인 주도 설계의 기법 중 하나이다.
다양한 컴포넌트가 메시지나 이벤트를 통해 서로 통신한다고 가정한다.
따라서 팀은 요구사항과 식별된 역할에 따라 시스템에서 어떤 이벤트가 일어나는지 파악하고 컴포넌트를 이벤트와 메세지 핸들러 중심으로 구축한다.
워크플로 접근법
워크플로 접근법은 이벤트 스토밍의 대안으로서, DDD나 메시징을 사용하지 않는 더 일반화한 방법이다.
지금까지 살펴본 기법들은 다 일장일단이 있으므로 어느 것이 다른 것보다 우월하다고 할 수 없다.
마찬가지로 정답은 없기 때문에 상황에 맞게 잘 대입하는 것이 중요한 능력이다.
느낀점
와우 정말 어렵다.. 정말 부분부분만 이해가 가능해서 많이 검색해보면서 읽은 것 같다..ㅠ
논의사항
9. 기초
아키텍처 스타일에 관한 글
아키텍처 스타일은 유저 인터페이스와 백엔드 소스 코드를 구성하는 방법, 그리고 소스 코드가 데이터 저장소와 상호작용하는 방법에 관한 결정적으로 중요한 구조이다.
이와 달리 아키텍처 패턴은 아키텍처 스타일에서 특정한 솔루션을 마련하는 데 유용한 저수준의 설계 구조를 말한다.
아키텍처 스타일은 종종 아키텍처 패턴이라고 부르며, 다양한 아키텍처 특성을 다루는 컴포넌트 명명된 관계를 기술한다.
아키텍처 스타일의 명칭은 숙련된 아키텍트 사이에서 간명하게 지정할 수 있는 이름으로 붙여 놓았다.
만약 아키텍트가 레이어드 모놀리스식 구조에 대해서 이야기 할 경우 구조적인 측면과 어떤 종류의 아키텍처 특성이 알맞는지 살펴보고 통상적인 배포 모델과 데이터 전략 등 다양한 정보를 이해하는 것이다.
따라서 아키텍트는 기초적인 아키텍처 스타일의 명칭에 익숙해져야 한다.
9.1 기초 패턴
소프트웨어 아키텍처의 역사를 통틀어 끊임없이 나타나고 또 나타나는 패턴이 있는데,, 이런 패턴들은 코드, 배포, 또는 아키텍처의 다른 부분을 구성하는 시야를 넓혀준다.
9.1.1 진흙잡탕
뭐 하나 뚜렷한 아키텍처 구조가 전무한 상태를 진흙잡탕이라고 표현한다.
진흙잡탕은 대충 되는 대로, 아무렇게나 막 지저분하게, 테이프를 덕지덕지 붙여 놓은 스파게티 코드 정글이다.
진흙 잡탕은 요즘에는 보통 실제 내부 구조라 할 만한 것은 하나도 없는, 데이터베이스를 직접 호출하는 이벤트 핸들러를 가진 단순한 스크립팅 애플리케이션을 가리킨다.
이런 구조는 규모가 커지면서 처지 곤란한 상태가 되어버린다..
아키텍트는 무슨 수를 써서라도 이런 아키텍처는 피하려고 한다. 구조가 없으면 앞으로 뭔가 변경하기 까다로워 지고 배포, 확장, 성능 역시 고통스럽기 때문이다.
9.1.2 유니터리 아키텍처
컴퓨터의 발전에 따라 단일 시스템에서 분산형 시스템이 등장하였다.
이제 유니터리 시스템은 임베디드 시스템과 그 밖에 매우 제약이 많은 극소수 환경을 제외하면 거의 쓰이지 않는다.
소프트웨어 시스템은 시간이 지날 수록 성능, 확장 등의 운영 아키텍처의 특성을 유지하려면 관심사를 분리할 필요가 있다.
9.1.3 클라이언트/서버 서버
시간이 갈수록 단일 시스템에서 여러 기능을 분리할 필요성이 대두되었고 그 분리 방법은 많은 아키텍처 스타일의 기초가 되었다.
프런트엔드와 백엔드로 기술적으로 기능을 분리한 2티어또는 클라이언트/서버 아키텍처는 대표적인 기본 아키텍처 스타일이다.
이 아키텍처는 시대와 컴퓨팅 파워에 따라 여러가지 형태로 존재해왔다.
데스크톱 + 데이터베이스 서버
데이터는 별도의 데이터베이스 서버로 분리하여 계산량이 많은 액션은 탄탄한 데이터베이스 서버에서 실행하고, 프레젠테이션 로직은 데스크톱에 두는 방식
브라우저 + 웹 서버
현대 웹 개발 시대가 도래하면서 웹 브라우저가 웹 서버에 접속하는 형태로 분리하는 것이 일반화되었다.
이로써 클라이언트는 가벼운 브라우저로 대체 되고, 내외부 방화병 모두 더 넓은 범위로 배포가 가능해졌다.
데이터베이스는 웹 서버와 분리되어 있지만 두 서버 모두 운영 센터 내부의 동급 머신에서 운용되고 유저 인터페이스는 브라우저에서 실행되므로 여전히 이 구조를 2티어로 바라보는 아키텍트도 있다.
3티어
1990년대 후반에 인기를 끈 3티어 아키텍처는 더 많은 레이어로 분리하며, 자바, 닷넷 진영에서 애플리케이션 서버같은 도구가 보급되고 기업들은 더 많은 레이어를 토폴로지에 구축하기 시작했다.
그 결과 데이터베이스 서버를 사용하는 데이터베이스 티어, 애플리케이션 서버가 관리하는 애플리케이션 티어, 그리고 HTML로 시작하여 점점 많아져 온갖 자바스크립트 코드가 가득 찬 프런트엔드 티어 이렇게 세 티어가 완성됐다.
3티어 아키텍처는 분산 아키텍처에 적합한 공통 객체 요청 브로커 아키텍처, 분산 컴포넌트 객체 모델같은 네트워크 수준의 프로토콜과 잘 맞았다.
9.2 모놀리식 대 분산 아키텍처
아키텍처 스타일은 크게 (전체 코드를 단일 단위로 배포하는) 모놀리식과 (원격 액세스 프로토콜을 통해 여러 단위로 배포하는)분산형, 두 종류이다.
이 세상에 완벽한 분류 체계는 없겠지만, 분산 아키텍처는 모놀리식 아키텍처 스타일에서 찾아볼 수 없는 공통적인 난제와 이슈를 갖고 있으므로 다양한 아키텍처 스타일을 분류하기 좋은 기준이다.
분산 아키텍처 스타일은 모놀리식 아키텍처 스타일에 비해 성능, 확장성, 가용성 측면에서 휠씬 강력하지만, 이런 파워도 결코 무시할 수 없는 트레이드오프가 수반된다.
이런 오류(옳다고 믿거나 가정하지만 사실 틀린 것)는 과거에서 부터 오늘날 까지도 적용되고 있다.
9.2.1 오류 1: 네트워크는 믿을 수 있다
개발자, 아키텍트 모두 네트워크를 믿을 수 있다고 전제하지만 실제로는 전혀 그렇지 않다.
분산 아키텍처는 그 특성상 서비스를 오가는, 또 서비스 간에 이동하는 네트워크에 의존하므로 이것은 아주 중요한 문제이다.
그림과 같은 서비스가 서로 응답하지 못하는 경우를 생각해서 타임아웃 장치나 회로 차단기(서킷 브레이커)를 두는 것이다.
시스템이 네트워크에 더 의존할수록 시스템의 신뢰도는 잠재적으로 떨어질 가능성이 있다.
9.2.2 오류 2: 레이턴시는 0이다
메서드나 함수를 이용해 다른 컴포넌트를 로컬 호출하면 그 소요시간은 나노 초 내지 밀리초 단위로 측정되지만, 동일한 호출을 원격 액세스 프로토콜을 통해서 수행하면 서비스 액세스 시간이 밀리초 단위로 측정된다.
따라서 두 시간의 차이는 발생할 수 밖에 없고 모든 분산 아키텍처에서 레이턴시는 0이 아니다.
아키텍트는 어떤 분산 아키텍처를 구축하든지 평균 레이턴시는 반드시 알아야 한다.
이것이 분산 아키텍처가 실현 가능한지 판단하는 유일한 방법이다.
9.2.3 오류 3: 대역폭은 무한하다
모놀리식 아키텍처는 비즈니스 요청을 처리하는 데 그리 큰 대역폭이 필요하지 않으므로 대역폭이 문제될 일은 별로 없다.
하지만 마이크로 서비스 분산 아키텍처에서 시스템이 자잘한 배포 단위로 쪼개지면 이 서비스들 간에 주고 받는 통신이 대역폭을 상당히 점유하여 네트워크가 느려지고 결국 레이턴시와 신뢰성에도 영향을 준다.
9.2.4 오류 4: 네트워크는 안전하다
아키텍트와 개발자는 대부분 가상사설망(VPN), 신뢰할 수 있는 네트워크, 방화벽에 익숙해진 나머지 네트워크가 안전하지 않다는 사실을 망각하는 경향이 있다.
보안은 분산 아키텍처에서 훨씬 더 어려운 문제이다. 모놀리식에서 분산아키텍처로 옮아가면서 더 넓은 영역이 악의적인 외부인의 위협과 공격에 노출된다.
9.2.5 오류 5: 토폴로지는 절대 안 바뀐다
네트워크를 구성하는 모든 라우터, 허브, 스위치, 방화벽, 네트워크, 어플라이언스등 전체 네트워크 토폴로지가 불변일 거라는 가정은 섣부른 오해다..!
9.2.6 오류 6: 관리자는 한 사람뿐이다
네트워크 관리자는 혼자가 아니라 여러 사람이다.
아키텍트는 언제나 한 사람의 관리자와 협의하고 소통하면 된다는 오류에 빠지곤 한다.
9.2.7 오류 7: 운송비는 0이다
많은 소프트웨어 아키텍트들이 이 오류를 레이턴시와 혼동한다.
여기서 운송비는 레이턴시가 아니라. “단순한 REST 호출”을 하는 데 소요되는 진짜 비용을 말한다.
아키텍트는 단순 REST 호출을 하거나 모놀ㄹ식 애플리케이션을 분리하는 데 필요한 충분한 인프라가 갖춰졌다고 오만한다.
9.2.8 오류 8: 네트워크는 균일하다
아키텍트, 개발자는 대부분 네트워크가 균일하다.
즉, 어느 네트웤 하드웨어 업체 한 곳에서 모든 장비를 다 만들었다고 착각한다.
하지만 실제 많은 회사의 인프라는 여러 업체의 네트워크 하드웨어 제품들이 엃히고 설켜 있다.
9.2.9 오류 9: 다른 분산 아키텍처 고려 사항
지금까지 열거한 8가지 오류와 더불어, 모놀리식 아키텍처에는 없지만 분산 아키텍처를 설계할 때 맞닥뜨리게 될 이슈 및 해결해야 할 난제들이 있습니다.
분산 로깅
분산 아키텍처는 애플리케이션과 시스템 로그가 분산되어 있으므로 어떤 데이터가 누락된 근본 원인을 밝혀내기가 어렵다.
분산 트랜잭션
모놀리식 아키텍처 세계에서 아키텍트, 개발자는 관리가 편한 트랜잭션을 당연시 한다.
하지만 분산 아키텍처는 최종 일관성이라는 개념을 바탕으로 분리된 배포 단위에서 처리된 데이터를 미리 알 수 없는 어느 시점에 모두 일관된 상태로 동기화한다.
계약 관리 및 버저닝
계약 생성, 유지보수, 버저닝 역시 분산 아키텍처에서 다소 까다롭다.
계약은 클라이언트 와 서비스 모두 합의한 행위와 데이터이다.
분산 아키텍처에서는 분리된 서비스와 시스템을 제각기 다른 팀과 부서가 소유하기 때문에 계약 유지보수가 특히 어렵다..
느낀점
아키텍처 스타일에서 분산 부분의 용어를 많이 들어봤지만.. 여기서 조금 정리가 된 느낌이다.
스타일에 대한 정의와 실제로 적용되는 사례들을 봐서 그런지 이해가 잘 된 편이다.
논의사항
10. 레이어드 아키텍처 스타일
레이어드 아키텍처는 가장 흔한 아키텍처 스타일 중 하나이다.
대중적이면서 비용도 적게 들어 모든 애플리케이션의 사실상 표준 아키텍처이다.
시스템을 설계하는 조직은 그 조직의 소통 구조를 그대로 복제한 듯 설계할 수 밖에 없다는 콘웨이 법칙을 떠올려보면, 레이어드 아키텍처는 애플리케이션을 개발하는 아주 자연스러운 방법이다.
UI 개발자, 백엔드, 규칙 개발자, 데이터베이스 개발자 등이 어느 회사던 있기 때문에 이런 조직의 전통적인 레이어드 아키텍처와 잘 맞아 떨어지니 많은 사랑을 받게 되었다.
그러나 아키텍처 스타일은 묵시적 아키텍처 안티패턴, 우발적 아키텍처 안티패턴 등의 몇몇 아키텍처 안티패턴 범주에 속한다.
10.1 토폴로지
레이어드 아키텍처에서 내부 컴포넌트는 논리적으로 수평한 레이어들로 구성되며, 각 레이어는 애플리케이션에서 주어진 역할을 수행한다.
레이어의 개수와 유형은 특별한 제한이 없지만, 일반적으로 프레젠테이션, 비즈니스, 퍼시스턴스, 데이터베이스의 4개 표준 레이어로 구성한다.
퍼시스턴스 로직이 비즈니스 레이어 컴포넌트에 내장된 경우에는 퍼시스턴스 레이어를 비즈니스 레이어에 병합시킨다.
따라서 규모가 작은 애플리케이션은 3개 크고 복잡한 애플리케이션은 5개 또는 그 이상으로 구성된다.
물리적 계층화 관점에서 다양하게 토폴로지룰 변형할 수 있다.
각 레이어는 주어진 비즈니스 요청을 충족하는 데 필요한 업무 위주로 추상화되어 있다.
예를 들어 프레젠테이션 레이어는 고객 데이터를 조회하는 방법은 알 필요가 없고 그럴 이유도 없다.
그저 받아온 정보를 화면에 보기 좋게 보여주면 그만이다. 반대의 경우도 동일하다.
이러한 관심사의 분리 개념 덕분에 레이어드 아키텍처 스타일은 아키텍처 내부의 역할 및 책임 모델을 효과적으로 구성할 수 있다.
특정 레이어에 소속된 컴포넌트는 역할 범위가 한정되며 그 레이어에 알맞는 로직만을 처리한다.
따라서 개발자는 기술적인 부분에 집중시킬 수 있지만, 그런 장점을 대가로 전체적인 민첩성이 떨어지는 트레이드오프가 있다.
중요
레이어드 아키텍처는 (도메인 분할 아키텍처의 반대인) 기술 아키텍처이다.
즉 컴포넌트를 도메인 단위로 묶는게 아니라 아키텍처의 기술역할에 따라 묶기 때문에 비즈니스 도메인이 각각 모든 아키텍처 레이어에 분산된다.
예를 들어 고객
도메인은 프레젠테이션 레이어, 비즈니스 레이어, 퍼시스턴스 레이어, 데이터베이스 레이어에 모두 포함하기 때문에 이 도메인에 변경을 가하는 일은 쉽지 않다.
도메인 주도 설계 방식과 잘 맞지 않는다.
10.2 레이어 격리
레이어드 아키텍처의 각 레이어는 폐쇄또는 개방 상태이다.
폐쇄 레이어란, 요청이 상위 레이어에서 하위 레이어로 이동하므로 중간의 어떤 레이어도 건너뛸 수 없고 현재 레이어를 거쳐야 바로 그 다음 레이어로 나아갈 수 있다는 뜻이다.
하지만 모든 레이어를 거칠 필요가 없는 작업이라면 직접 액세스하는 편이 더 간편할 것이다.
다른 요청을 수행하려면 해당 레이어가 개방되어 있어야 하는데 과연 폐쇄와 개방 어느 것이 좋을지는 .. 레이어 격리를 이해해야 가능하다.
레이어 격리란, 어느 아키텍처 레이어에서 변경이 일어나도 다른 레이어에 있는 컴포넌트에 아무런 영향을 끼치지 않기에 레이어 간 계약은 불변임을 의미한다.
각 레이어는 서로 독립적으로 작동되므로 다른 레이어의 내부 동작로직은 거의/전혀 알지 못한다.
레이어 격리를 지원하려면 요청의 메인 흐름에 관한 레이어가 반드시 폐쇄되어 있어야 한다.
퍼시스던트 레이어에서 변경이 발생할 경우 비즈니스 레이어, 프레젠테이션 레이어 둘 다 영향을 받게 되고, 결국 컴포넌트 간의 레이어 상호 의존도가 높아져서 단단히 커플링된 애플리케이션이 될 것이다.
이런 아키텍처는 매우 취약하고 변경하기 힘들고 비용도 많이 든다.
10.3 레이어 추가
아키텍처 내부적으로 폐쇄 레이어를 이용해 변경을 격리할 수 있지만, 어떤 레이어는 개방을 하는 경우가 더 합리적인 경우가 있다.
예를 들어 비즈니스 레이어에 공통 비즈니스 기능이 구현된 객체를 구현하여 공유하고, 프레젠테이션 레이어에서는 이 공유 객체를 직접 사용할 수 없도록 아키텍처 결정을 했다고 한다.
이 시나리오는 프레젠테이션 레이어가 비즈니스 레이어를 액세스 할 수 있고 그 내부의 공유 객체 역시 갖다 쓸 수 있는, 지배/통제하기 어려운 아키텍처 구조이다.
이런 제약조건을 아키텍처적으로 강제하려면 공유 비즈니스 객체가 모두 포함된 새로운 서비스 레이어를 아키텍처에 추가하면 된다.
해당 레이어를 개방하여 접근을 간결하게 한다.
10.4 기타 고려 사항
아직 아키텍처 스타일을 완전히 정하지 못했다면 대부분의 어플리케이션에서 레이어드 아키텍처는 좋은 출발점이 될 것이다.
마이크로서비스 아키텍처를 고려 중인데 과연 마이크로서비스가 올바른 선택인지 긴가민가하고 어쨌든 개발은 시작해야 할 때도 그렇다.
하지만 재사용은 최소한, 객체 계층은 최대한 가볍게 맞추어 적절한 모듈성을 유지하는 것이 중요
레이어드 아키텍처에선 아키텍처 싱크홀 안티패턴을 조심해야 한다.
불필요한 객체 초기화 및 처리를 빈번하게 유발하고 쓸데없이 메모리를 소모하며 성능에도 부정적인 영향을 끼친다.
10.5 왜 이 아키텍처 스타일을 사용하는가
레이어드 아키텍처는 작고 단순한 애플리케이션이나 웹사이트에 알맞는 아키텍처 스타일이다.
특히 처음 구축을 시작할 때, 예산과 일정이 빠듯한 경우 출발점으로 괜찮은 아키텍처 선택이다.
레이어드 아키텍처 기반의 애플리케이션은 규모가 커질수록 유지 보수성, 민첩성, 시험성, 배포성 같은 아키텍처 특성이 점점 나빠진다.
따라서 레이어드 아키텍처를 사용한 대규모 애플리케이션이나 시스템은 다른 더 모듈러한 아키텍처 스타일이 더 잘 맞습니다.
10.6 아키텍처 특성 등급
아키텍처 특성을 각 아키텍처 스타일에 맞게 표로 나타내어져 있다.
전체 비용과 단순성은 레이어드 아키텍처의 주요 강점이다.
이 아키텍처는 모놀리식에 가깝기 때문에 분산 아키텍처 스타일에 따른 복잡도가 낮고, 구조가 단순해서 알기 쉬운데다 구축 및 유지보수 비용도 적게 든다.
느낀점
레어어로 구분하여 개발을 하는 방식이 레이어드 아키텍처인지 처음 알았다;;
앞으로도 다른 방법을 배운다고 하니 기대가 된다.
논의사항
11. 파이프라인 아키텍처 스타일
파이프라인 아키텍처 스타일은 소프트웨어 아키텍처에서 끊임없이 등장하는 기본적인 아키텍처 스타일이다.
개발자와 아키텍트가 기능을 개별로 분리하기로 결정하는 순간부터 이 패턴이 수반된다.
이 아키텍처는 Bash, Zsh같은 유닉스 터미널 쉘 언어의 기초 원리이다..!?
함수형 언어 개발자는 언어 구조와 이 아키텍처 요소가 유사하다고 생각할 것이다.
사실 맵리듀스 프로그래밍 모델을 응용한 많은 도구가 이 기본 토폴로지를 따른다.
따라서 이 스타일은 저수준, 고수준 모두에서 사용할 수 있다.
11.1 토폴로지
파이프라인 아키텍처는 다수의 파이프와 필터로 구성된다.
파이프와 필터는 특정한 방식으로 조정되며, 보통 필터 간 단방향 통신은 점대점 방식으로 구성한다.
11.1.1 파이프
파이프는 한 소스에서 입력을 받아 다른 소스로 출력을 내는, 필터 간 통신 채널이다.
파이프는 성능상의 이유로 보통 단방향, 점대점 방식으로 구성한다.
11.1.2 필터
필터는 자기 완비형이고, 다른 필터와 독립적이며, 일반적으로 무상태성이다.
필터는 한 가지 테스크만 수행하므로 복합 테스크는 여러 필터를 이어 붙여 처리하면 된다.
파이프라인 아키텍처 스타일에서 필터는 다음 네 가지 종류가 있다.
- 프로듀서
- 프로세스의 시작 점으로 아웃바운드 만 있어서(들어오는 트래픽은 없고 나가는 트래픽만 있다) 소스라고도 한다.
- 변환기
- 입력을 받아 필요시 일부 또는 전체 데이터를 반환한 후, 그 결과를 아웃바운드 파이프로 전달한다.
- 이 기능을 함수형 프로그래밍에서는
맵
이라고 부른다.
- 테스터
- 입력을 받아 하나 이상의 기준에 대해 테스트를 하고 그 결과에 따라 필요시 결과를 생산한다.
- 이 기능을 함수형 프로그래밍에서는
리듀스
이라고 부른다.
- 컨슈머
- 파이프라인 흐름의 종착역이다.
- 컨슈머는 파이프라인 프로세스의 최종 결과를 데이터베이스에 저장하거나 유저 인터페이스에 표시한다.
각 파이프와 필터는 단방향이고 워낙 단순해서 얼마든지 조합할 수 있다(모듈성)
11.2 예제
파이프라인 아키텍처 패턴은 다양한 애플리케이션과 특히 간단한 단방향 처리 태스크에서 흔히 찾아볼 수 있다.
전자 데이터 교환(EDI)도구,ETL도구 등이 대표적이다.
11.3 아키텍처 특성 등급
파이프라인 아키텍처 스타일은 애플리케이션 로직을 필터 타입에 따라 나누는, 기술 분할 아키텍처이다.
보통 모놀리식 형태로 구현/배포하므로 아키텍처 퀀텀은 언제나 1이다.
이 아키텍처의 주요 강점은 모듈성과 결부된 전체 비용 및 단순성이다.
원래 모놀리식에 가깝기 때문에 분산 아키텍처에 수반되는 복잡도가 없고, 단순해서 알기 쉽고 구축 및 유지보수 비용도 비교적 적게 든다.
평균 수준으로 매긴 배포성, 시험성은 필터를 통한 모듈성이 더 우수하므로 레이어드 아키텍처보다는 조금 낫다.
그래도 이 아키텍처 스타일은 모놀리식라서 절차, 리스크, 배포 빈도, 테스트 완성도의 영향을 받는다.
레이어드와 마찬가지로 분산 아키텍처에서 자주 목격되는 네트워크 트래픽, 대역폭 부족, 레이턴시 탓에 전체 신뢰성은 중간정도이다.
이 아키텍처는 탄력성과 확장성은 모놀리식 배포 때문에 점수가 낮고 내고장성도 별로다.
느낀점
교조주의, 이게 최고야에 빠지는 경우가 해당 아키텍처가 유리한 상황에서만 개발을 해서 그런 것 같다고 느낀 것 같다.
다른 시스템이나 아키텍처를 둘러보면 트레이드 오프가 당연하지만 트레이드 오프를 생각하지 못하고 시야가 좁아지는 것 같다.
논의사항
12. 마이크로커널 아키텍처 스타일
이미 수십 년 전에 만들어진 마이크로커널 아키텍처는 오늘날에도 많이 쓰이고 있다.
이 아키텍처 스타일은 제품 기반 애플리케이션에 적합하며, 비제품 고객 비즈니스 애플리케이션에서도 많이 쓰인다.
12.1 토폴로지
마이크로커널 아키텍처 스타일은 코어 시스템과 플러그인 컴포넌트라는 두 가지 아키텍처 요소로 구성된 비교적 단순한 모놀리식 아키텍처이다.
애플리케이션 로직은 독립적인 플로그인 컴포넌트와 기본 코어 시스템에 골고루 분산되어 확장성, 적응성, 애플리케이션 기능 분리, 커스텀 처리등을 수행한다.
12.1.1 코어 시스템
코어 시스템은 시스템을 실행시키는 데 필요한 최소한의 기능으로 정의한다.
이클립스(IDE)가 좋은 예이다.
이클립스 코어 시스템은 파일을 열고, 텍스트를 고치고, 다시 파일을 저장하는 기본적인 텍스트 에디터에 불과하다.
플러그인을 추가하여야 비로소 쓸만한 제품이 된다.
코어 시스템은 커스터 처리가 거의/전혀 필요없는, 애플리케이션을 관통하는 정상 경로라고 정의할 수 있다.
코어 시스템의 순환 복잡도를 없애고 별도의 플러그인 컴포넌트를 장착하면 확장성, 유지보수성은 물론 시험성도 좋아진다.
코어 시스템은 규모와 복잡도에 따라 레이어드 아키텍처나 모듈러 모놀리스로 구현할 수 있다.
경우에 따라 코어 시스템은 별도 배포하는 도메인 서비스로 나누어 서비스별 도메인에 특정한 컴포넌트를 둘 수도 있다.
12.1.2 플러그인 컴포넌트
플러그인 컴포넌트는 특수한 처리 로직, 부가 기능, 그리고 코어 시스템을 개선/확장하기 위한 커스텀 코드가 구현된 스탠드얼론 컴포넌트이다.
변동성이 매우 큰 코드를 분리하여 애플리케이션 내부의 유지보수성, 시험성을 높이는 것이다.
이상적인 플러그인 컴포넌트는 상호 독립적이며 의존성이 없다.
플러그인 컴포넌트와 코어 시스템은 일반적으로 점대점통신을 한다.
즉, 코어 시스템에 플러그인을 연결하는 파이프
는 대부분 플러그인 컴포넌트의 진입점 클래스를 호출하는 메서드나 함수 코드이다.
c#
을 예로 인터페이스로 관리한다.
플러그인 컴포넌트가 반드시 코어 시스템과 점대점 통신을 해야하는 것은 아니다.
각 플러그인을 스탠드얼론 서비스로 만들어 REST나 메시징 등 다른 방법으로 기능을 호출하는 방법도 있다.
12.2 레지스트리
코어 시스템이 어떤 플러그인을 사용할 수 있는지, 그 플러그인을 가져오려면 어떻게 해야하는지 알고 있어야 한다.
가장 일반적인 구현 방법은 플러그인 레지스트리를 경유하는 것이다.
레지스트리는 코어 시스템이 소유한 내부 맵 구조처럼 단순할 수도 있고, 레지스트리 및 디스커버리 도구가 코어 시스템이나 외부 배포된 시스템에 내장된 복잡한 형태일 수도 있다.
12.3 계약
플러그인 컴포넌트와 코어 시스템 간의 계약은 보통 플러그인 컴포넌트의 도메인 단위로 표준화되어 있고, 플러그인 컴포넌트가 수행하는 기능 및 입출력 데이터는 계약에 명시되어 있다.
12.4 실제 용례
이클립스, 젠킨스 등 많은 소프트웨어 개발/릴리스 도구가 마이크로커널 아키텍처 스타일을 사용한다.
크롬또한 마이크로커널 아키텍처를 응용한 제품으로 각종 뷰어와 플러그인이 장착가능하다.
VsCode도 마이크로 커널 아키텍처인 것 같다.
12.5 아키텍처 특성 등급
레이어드 아키텍처와 같이 단순성과 전체비용이 주요 강점이다.
반면 고질적인 모놀로식 배포 탓에 탄력성, 내고장성, 확장성이 문제가 될 때가 많다.
모든 요청은 코어 시스템을 통해 유입되어 독립적인 플러그인 컴포넌트로 흘러가므로 퀀텀은 언제나 1이다.
마이크로 커널 아키텍처는 도메인 분할, 기술 분할이 모두 가능한 유일한 아키텍처 스타일이다..!
기능을 독립적인 플러그인 컴포넌트로 분리할 수 있으므로 시험성, 배포성, 신뢰성은 평균보다 약간 높게 책정된다.
모듈성은 3개, 성능도 3개이다.
느낀점
마이크로 커널 아키텍처가 이거구나 정도로 이해한 것 같다..
논의사항
13. 서비스 기반 아키텍처 스타일
서비스 기반 아키텍처는 마이크로서비스 아키텍처 스타일의 일종으로 아키텍처가 유연해서 가장 실용적인 아키텍처 스타일 중 하나이다.
마이크로 서비스나 이벤트 기반 아키텍처와 마찬가지로 분산 아키텍처지만 비교적 덜 복잡하고 비용이 많이 들지 않아서 많은 비즈니스 관련 애플리케이션에 널리 채택된 아키텍처이다..!
13.1. 토폴로지
서비스 기반 아키텍처의 기본 토폴로지는 각각 따로 배포된 유저 인터페이스와 원격 서비스, 그리고 모놀리스 데이터베이스로 이루어진 대규모 분산 레이어 구조이다.
이 아키텍처 스타일에서 서비스는 큼지막한 단위로 분리해 별도로 배포하는 애플리케이션의 일부
이다.
서비스를 배포하는 방식 자체는 여느 모놀리식 애플리케이션과 동일하므로 컨테이너화는 필수가 아니다..!
여러 서비스가 단일 모놀리식 데이터베이스를 공유하므로 애플리케이션 서비스는 다 합쳐도 4 ~ 12개 평균 7개 정도이다.
서비스 기반 아키텍처의 도메인 서비스는 각각 단일 인스턴스로 배포하지만, 확장성, 내고장성, 처리량 요구사항에 따라 인스턴스를 여럿 둘 수도 있다.
서비스는 원격 액세스 프로토콜로 유저 인터페이스 외부에서 접속할 수 있다.
서비스 기반 아키텍처는 중앙 공유 데이터 베이스를 사용한다는 특징이 중요하다.
13.2. 토폴로지 변형
서비스 기반 아키텍처 스타일은 특유의 유연성 때문에 정말 다양한 변형이 존재한다.
단일 모놀리식 유저 인터페이스는 다시 여러 유저 인터페이스 도메인으로 나눌 수 있고, 각 도메인 서비스에 맞게 나눌 수 있다.
또, 단일 모놀리식 데이터베이스를 개별 데이터베이스로 분리할 수 있고, 각 도메인 서비스 전용 데이터베이스들로 쪼갤 수 있다.
13.3. 서비스 설계 및 세분도
서비스 기반 아키텍처의 도메인 서비스는 보통 단위가 크기 때문에 도메인 서비스를 API 퍼사드 레이어, 비즈니스 레이어, 퍼시스턴스 레이어로 구성된 레이어드 아키텍처 스타일로 설계하는 것이 일반적이다.
서비스를 어떻게 설계하든 도메인 서비스는 유저 인터페이스에서 비즈니스 기능을 호출하기 위해 접속할 일종의 API 액세스 퍼사드를 필요로 한다.
퍼사드 패턴 참고,,
API 액세스 퍼사드는 유저 인터페이스를 통해 유입된 비즈니스 요청을 오케스트레이트하는 역할을 한다.
세분도 관점에서 내부 클래스 수준의 오케스트레이션과 외부 서비스의 오케스트레이션이라는 차이점이 서비스 기반 아키텍처와 마이크로서비스의 중요한 차이점이다.
도메인 서비스는 단위가 커서 데이터 무결성과 일관성 측면에서는 유리하지만 그에 못지않은 트레이드 오프도 있다.
13.4. 데이터베이스 분할
서비스 기반 아키텍처의 서비스는 주어진 애플리케이션 콘텍스트에서 서비스 수가 적은 편이라 보통 단일 모놀리식 데이터베이서를 공유한다.
그러나 이러한 데이터베이스 커플링은 테이블 스키마 변경 시 문제가 될 수 있다.
테이블 스키마를 올바르게 변경하지 않을 경우 모든 서비스에 악영향을 미치기 때문에 데이터베이스 변경은 여러모로 노력과 조정이 필요한 값비싼 작업이다.
예제와 같이 단일 공유 라이브러리를 사용하면 데이터배이스 테이블 하나를 바꿔도 모든 서비스에 양행을 미친다.
이러한 리스크를 낮추는 방법은 데이터베이스를 논리적으로 분할하고 이러한 논리 분할을 연합 공유 라이브러리를 통해 명시하는 것이다.
13.5. 아키텍처 예시
서비스 기반 아키텍처의 유연함을 볼 수 있다.
13.6. 아키텍처 특성 등급
서비스 기반 아키텍처는 도메인 분할된 아키텍처이다.
즉, 기술 관심사보다 도메인 위주로 구성된 아키텍처이고, 소프트웨어 단위로서 그 범위가 특정 도메인으로 한정된다.
따라서 나중에 해당 도메인을 변경할 일이 생겨도 해당 서비스, 해당 유저 인터페이스만 영향 받을 뿐 다른 부분을 고칠 필요가 없다..!
분산 아키텍처 이므로 퀀텀도 하나 이상을 가지며 동일한 데이터베이스나 유저 인터페이스를 공유할 경우 전체 시스템 퀀텀은 1이다.
전체적으로 5점은 없지만 평균이 매우 높다.
신속한 변경(민첩성), 도메인 범위가 한정되어 테스트 커버리지가 향상(시험성), 덩치가 큰 모놀리스보다 덜 위험하게, 더 자주 배포될 수 있다.(배포성)
내고장성, 확장성또한 분산 아키텍처의 특성이므로 높다.
13.7. 언제 이 아키텍처 스타일을 적용하는가
서비스 기반 아키텍처는 매우 실용적인 아키텍처이다.
이 보다 더 강력한 분산 아키텍처 스타일도 있지만! 그 강력함은 곧 가파른 비용 상승을 동반하고 그렇게 까지 강력할 필요가 없음을 알게 된다. (트레이드 오프)
서비스 기반 아키텍처는 도메인 주도 설계와 궁합이 잘 맞고 서비스를 큰 단위로 나누고 그 범위를 도메인으로 한정하기 때문에 각 도메인은 개별 배포된 도메인 서비스에 딱 맞아 떨어진다.
서비스 기반 아키텍처는 복잡하게 뒤얽히거나 세분도의 함정에 빠져 허우적거리지 않고도 아키텍처 모듈성을 괜찮은 수준으로 달성할 수 있다.
느낀점
분산에 들어오니 모놀리식의 연장이라고 생각되는데..(하나의 도메인 서비스를 하나의 레이어드 아키텍처로 설계한다는 부분에서) 좀 더 추상적으로 다루다 보니 이렇게 설계가 된 것 같다.
게임쪽에서 과연 이런 분산 아키텍처를 사용하는 경우가 있을까..? 라는 생각이 든다..
논의사항
논외로 질문이 있습니다.. 모놀리스와 분산아키텍처를 책에서 보여주는 순서가 많이 사용되는 아키텍처 순서인가요?
++ 책에서 소개된 아키텍처 말고도 다양한 아키텍처가 있는건지..
14. 이벤트 기반 아키텍처 스타일
이벤트 기반 아키텍처는 확장성이 뛰어난ㄴ 고성능 애플리케이션 개발에 널리 쓰이는 비동기 분산 아키텍처 스타일이다.
적응성이 매우 좋아 소규모부터 대규모까지 두루 사용할 수 있다.
이벤트 기반 아키텍처는 이벤트를 비동기 수신/처리하는 별도의 이벤트 처리 컴포넌트로 구성되며, 스탠드 얼론 아키텍처 스타일로 사용하거나 다른 아키텍처 스타일에 내장할수도 있다.
이 모델은 어떤 액션을 수행하도록 시스템에 요청하면 요청 오케스트레이터가 접수한다.
요청 오케스트레이터는 보통 유저 인터페이스이지만 API 레이어나 엔터프라이즈 서비스버스로도 구현할 수 있다.
이 컴포넌트의 임무는 다양한 요청 프로세서에 확정적으로, 동기적으로 요청을 전달하는 일이다.
요청 프로세스는 요청을 받아 데이터베이스에서 정보를 조회/수정하는 등의 작업을 수행하는 식으로 요청한다..
14.1 토폴로지
이벤트 기반 아키텍처의 주요 토폴로지는 중재자 토폴로지, 브로커 토폴로지이다.
중재자 토폴로지는 이벤트 처리 워크플로를 제어해야 할 경우에, 브로커 토폴로지는 신속한 응답과 동적인 이벤트 처리 제어가 필요할 때 각각 사용된다.
두 토폴로지의 아키텍처 특성과 구현 전략은 서로 다르기 때문에 주어진 상황에 맞게 선택하려면 각각의 특징을 정확하게 이해해야 한다.
14.2 브로커 토폴로지
브로커 토폴로지는 중앙에 이벤트 중자재가 없다는 점에서 중재자 토폴로지와 다르다.
메시지는 경량 메세지 브로커를 통해 브로드캐스팅되는 식으로 이벤트 프로세서 컴포넌트에 분산되어 흘러간다.
이 토폴로지는 비교적 이벤트 처리 흐름이 단순하고 굳이 중앙에서 이벤트를 조정할 필요가 없을 때 유용하다.
브로커 토폴로지는 네 가지 기본 아키텍처 컴포넌트
시작 이벤트, 이벤트 브로커, 이벤트 프로세서, 처리 이벤트로 구성된다.
시작 이벤트는 단순한 이벤트든, 복잡한 이벤트든 전체 이벤트 흐름을 개시하는 이벤트를 말한다.
시작 이벤트는 이벤트 브로커의 이벤트 채널로 전송되어 처리된다.
이벤트를 관리/제어하는 중재자가 브로커 토폴로지에 없으므로 단일 이벤트 프로세서는 이벤트 브로커에서 시작 이벤트를 받자마자 관련된 처리 작업을 마친 뒤 처리 이벤트를 생성하고 시스템의 나머지 부분에 자신이 한 일을 비동기로 알린다.
이 처리 이벤트는 필요시 부가적인 처리를 위해 이벤트 브로커에 비동기 전송된다.
다른 이벤트 프로세서는 처리 이벤트를 리스닝하고 있다가 이벤트가 들어오면 그에 맞는 작업을 수행한 뒤 다시 새로운 처리 이벤트를 발행함으로 자신이 한 일을 모두에게 알린다.
장점 | 단점 |
---|---|
이벤트 프로세서가 디커플링됨. | 워크플로 제어. |
확장성이 높음 | 에러 처리 |
응답성이 우수함 | 복구성 |
성능 우수함 | 재시작 능력 |
내고장성 뛰어남 | 데이터 비일관성 |
14.3 중재자 토폴로지
중재자 토폴로지는 앞서 본 브로커 토폴로지의 단점을 일부 보완한다.
여러 이벤트 프로세서 간의 조정이 필요한 시작 이벤트에 대하여 워크플로를 관리/제어하는 이벤트 중재자가 핵심이다.
중재자 토폴로지는 시작 이벤트, 이벤트 큐, 이벤트 중재자, 이벤트 채널, 이벤트 프로세서 이렇게 5개 아키텍처 컴포넌트로 구성된다.
시작 이벤트가 전체 이벤트 프로세스를 개시하는 이벤트인 점은 브로커 토폴로지와 동일하지만, 중재자 토폴로지에서는 시작 이벤트 처리에 관한 단계 정보만 갖고 있으므로 점대점 메시징으로 각각의 이벤트 채널로 전달되는 처리 이벤트를 생성한다.
그러면 각 이벤트 프로세서는 자신의 이벤트 채널에서 이벤트를 받아 처리한 다음 중재자에게 작업을 완료했다고 응답한다.
이벤트 프로세서가 다른 프로세서에게 자신이 한 일을 알리지 않는다는 것도 브로커 토폴로지와 다른 점이다.
중재자 컴포넌트는 브로커 토폴로지와 달리 워크플로에 대해 잘 알고 있고 통제가 가능하다.
따라서 이벤트 상태를 유지하며 에러 처리, 복구, 재시작을 할 수 있다.
장점 | 단점 |
---|---|
워크플로 제어 | 이벤트 프로세서가 커플링됨 |
에러 처리 | 확장성이 떨어짐 |
복구 | 성능 낮음 |
재시작 | 내고장성 낮음 |
데이터 일관성 | 워크플로 모델링 복잡함 |
브로커 토폴로지냐 중재자 토폴로지냐 결국 워클플로 제어와 에러 처리 기능이 우선인가, 아니면 고성능과 확장성이 더 중요한가의 트레이드 오프를 잘 따라서 선택할 수 밖에 없다.
중재자 토폴로지의 성능과 확장성도 그리 나쁜편은 아니지만 아무래도 브로커 토폴로지만큼은 못 한 게 사실
14.4 비동기 통신
이벤트 기반 아키텍처 스타일은 요청/응답 처리뿐만 아니라 파이어 앤드 포켓 처리 모두 비동기 통신만 사용한다는 점에서 다른 아키텍처 스타일과 차별화된다.
비동기 통신은 시스템 응답성을 전반적으로 높이는 기법으로 사용할 수 있다.
비통기 통신에는 에러 처리가 가장 큰 문제이다.
응답성은 엄청나게 개선되지만 에러를 제대로 처리하기가 쉽지 않기 때문에 이벤트 기반 시스템의 복잡도가 가중된다.
14.5 에러 처리
리액티브 아키텍처의 워크플로 이벤트 패턴은 비동기 워크플로에서 에러 처리 문제를 해결하는 한 가지 방법이다.
탄력성, 응답성을 보장하는 리액티브 아키텍처 패턴의 일종이다.
14.6 데이터 소실 방지
비동기 통신을 할 때 데이터 소실은 언제나 중요한 부분인데, 이벤트 기반 아키텍처는 이러한 데이터 소실에 많이 노출되어 있다.
14.7 브로드캐스팅
이벤트 기반 아키텍처는 메시지를 누가 받든 그 메시지로 무슨 일을 하든 상관없이 이벤트를 브로드캐스트할 수 있다.
14.8 요청-응답
이벤트 기반 아키텍처는 동기 통신을 요청-응답 메시징방식으로 수행한다.
요청-응답 메시징 내부의 각 이벤트 채널은 요청 큐, 응답 큐로 구성된다.
처음 정보를 요청하면 요청 큐에 응답이 도착하길 기다리며 차단 대기 상태가 된다.
메시지 컨슈머가 메시지를 받아 처리한 후 응답 큐에 응답을 보내면 이벤트 프로듀서는 응답 데이터가 포함된 메시지를 수신한다.
14.9 요청 기반이냐, 이벤트 기반이냐
워크플로의 확장성과 제어가 중요하면 체계적인 데이터 기반의 요청에 특화된 요청 기반 모델을, 복잡하고 동적인 유저 처리 등 주로 고도의 응답성과 확장성을 요하는, 유연한 액션 단위의 이벤트를 처리한다면 이벤트 기반 모델이 좋은 선택이다.
14.10 하이브리드 이벤트 기반 아키텍처
이벤트 기반 아키텍처와 다른 아키텍처 스타일을 함께 사용하는 하이브리드 아키텍처 기반의 애플리케이션도 있다
이벤트 기반 아키텍처를 다른 아키텍처 스타일의 일부로 활용하는 아키텍처로 마이크로서비스 아키텍처, 공간 기반 아키텍처가 대표적이다.
14.11 아키텍처 특성 등급
단순성이 별 하나.. 아키텍트 입장에선 난이도정도인 것 같다..
기술 분할 아키텍처로 도메인 분할이 아니다.
이벤트 프로세서의 데이터베이스 상호작용 및 요청-응답 처리를 기반으로 하므로 퀀텀 수는 1개 이상 가능하다.
성능, 확장성, 내고장성, 진화성은 5점으로 처음보는 최고점 같다..
비결정적, 동적인 이벤트 흐름때문에 단순성과 시험성은 낮은 편이다.
느낀점
30%정도만 이해한 기분.. 댓글 예제와 데이터 소실 방지부분의 추상적인 기능정도만 이해가 된 것 같다.
논의사항
논의할 만한 주제를 고르기 너무 어렵네요..
비동기 통신이나 데이터 소실방지, 에러처리는 이 아키텍처에만 종속된게 아니라 개발 레벨이나 다른 아키텍처에도 응용될만한 내용인 것 같습니다.
15. 공간 기반 아키텍처 스타일
웹 기반 비즈니스 애플리케이션은 대부분 일반적인 요청 흐름을 따라간다.
브라우저에서 요청을 보내면 웹 서버, 애플리케이션 서버, 데이터베이스 서버 순서로 도달한다.
이런 패턴은 유저가 많지 않으면 별 문제없지만 유저 수가 늘어나면 점점 병목 현상이 나타나기 시작한다.
처음에는 웹 서버 레이어에서 발생하다가 나중에는 애플리케이션, 데이터베이스 서버 레이어에서도 발생한다.
유저 수 증가에 따른 병목 현상의 가장 일반적인 해결 방법은 웹 서버 확장이다.
이 방법은 비교적 쉽고 저렴하며 효과적으로 병목을 제거할 수 있지만, 유저 부하가 높을 때 웹 서버 레이어를 확장하면 병목점은 다시 애플리케이션 서버로 이동하기 쉽다.
애플리케이션 서버 확장은 웹 서버보다 휠씬 복잡하고 비용도 많이 드는데, 문제는 그렇게 확장 하더라도 다시 데이터베이스 서버가 병목점이 될 가능성이 높다는 것이다..
공간 기반 아키텍처 스타일은 높은 확장성, 탄력성, 동시성 및 이와 관련된 문제를 해결하기 위해 설계된 아키텍처 스타일이다.
동시 유저 수가 매우 가변적이라서 예측조차 곤란한 애플리케이션에서도 유용하다.
극단적이고 가변적인 확장성 문제는 데이터 베이스를 확장하거나, 확장성이 떨어지는 아키텍처에 맞게 캐시 기술을 적용하는 것보다 아키텍처적으로 해결하는 것이 낫다.
15.1 토폴리지
공간 기반 아키텍처라는 명칭은 튜플 공간에서 유래되었으며, 튜플 공간이란 공유 메모리를 통해 통신하는 다중 병렬 프로세서를 사용하는 기술이다.
시스템에서 동기 제약조건인 중앙 데이터베이스를 없애는 대신, 복제된 인메모리 데이터 그리드를 활용하면 확장성, 탄력성, 성능을 높일 수 있다.
애플리케이션 데이터는 메모리에 둔 상태로 모든 활성 처리 장치들이 데이터를 복제한다.
처리 장치는 데이터를 업데이트할 때 퍼시스턴스 큐에 메시지를 보내는 식으로 데이터베이스에 데이터를 비동기 전송한다.
따라서 유저 부하의 증가/감소에 따라 처리 장치는 동적으로 시작/종료할 수 있어 가변적으로 확장할 수 있다.
중앙 데이터베이스가 애플리케이션의 표준 트랜잭션 처리에 관여하지 않으므로 데이터베이스 병목 현상이 사라지고 애플리케이션은 거의 무한에 가까운 확장성이 보장된다.
공간 기반 아키텍처는 애플리케이션 코드가 구현된 처리 장치, 처리 장치를 관리/조정하는 가상 미들웨어, 업데이트된 데이터를 데이터베이스에 비동기 전송하는 데이터 펌프, 데이터 펌프에서 데이터를 받아 업데이트를 수행하는 데이터 라이터, 처리 장치가 시작되자마자 데이터베이스의 데이터를 읽어 전달하는 데이터 리더컴포넌트로 구성된다.
매우 복잡..
15.1.1 처리 장치
처리 장치는 애플리케이션 로직을 갖고 있다.
보통은 웹 기반 컴포넌트와 백엔드 비즈니스 로직이 포함되나 애플케이션 종류마다 내용물은 달라진다.
작은 웹 기반 애플리케이션은 단일 처리 장치에 배포할 수 있지만, 대규모 애플리케이션은 기능별로 여러 처리 장치에 나누어 배포해야 한다.
15.1.2 가상 미들웨어
가싱 미들웨어는 아키텍처 내부에서 데이터 동기화 및 요청 처리의 다양한 부분을 제어하는 인프라를 담당한다.
가상 미들웨어는 메시징 그리드, 데이터 그리드, 처리 그리드, 배포 관리자등의 컴포넌트로 구성된다.
- 메시징 그리드
- 입력 요청과 세션 상태를 관리한다.
- 가상 미들웨어에 요청이 유입되면 메시징 그리드는 어느 활성 처리 장치가 요청을 받아 처리할지 결정하여 해당 처리 장치로 요청을 전달한다.
- 데이터 그리드
- 데이터는 이름이 동일한 데이터 그리드가 포함된 차리 장치 간에 동기화된다.
- 처리 그리드
- 다수의 처리 장치가 단일 비즈니스 요청을 처리할 경우 요청 처리를 오케스트레이트하는 일을 한다.
- 또 종류가 다른 처리 장치 사이에 조정이 필요한 요청이 들어오면 처리 그리드가 이를 처리한다.
- 배포 관리자
- 부하 조건에 따라 처리 장치 인스턴스를 동적으로 시작/종료하는 컴포넌트이다.
15.1.3 데이터 펌프
데이터 펌프란, 데이터를 다른 프로세서에 보내 데이터베이스를 업데이트하는 장치이다.
공간 기반 아키텍처에서는 처리 장치가 데이터를 데이터베이스에 직접 읽고 쓰지 않으므로 데이터 펌프가 필요하다.
데이터 펌프는 항상 비동기적으로 동작하며 메모리캐시와 데이터베이스의 최종 일관성을 보장한다.
15.1.4 데이터 라이터
데이터 라이터란, 데이터 펌프에서 메시지를 받아 그에 맞게 데이터베이스를 업데이트하는 컴포넌트이다.
데이터 라이터는 서비스나 애플리케이션, 데이터 허브로 구현할 수 있다.
15.1.5 데이터 리더
데이터 라이터가 데이터베이스 업데이트를 담당한다면 데이터 리더는 데이터베이스에서 데이터를 읽어 리버스 데이터 펌프를 통해 처리 장치로 실어 나르는 컴포넌트이다.
15.2 데이터 충돌
이름이 동일한 캐시가 포함된 인스턴스에 시시각각 업데이트가 일어나는 active/acitve 상태에서 복제 캐시를 사용하면 복제 레이턴시때문에 데이터 충돌이 발생할 수 있다.
15.3 클라우드 대 온프레미스 구현
공간 기반 아키텍처는 배포 환경 측면에서 독자적인 선택지가 있다.
처리 장치, 가상 미들웨어, 데이터 펌프, 데이터 리더/라이타, 데이터 베이스 등 전체 토폴로지는 클라우드 기반의 환경이나 온프레미스에 배포할 수 있다.
하지만 이 두 환경 사이에 어중간하게 배포할 수 있는데, 이것이 다른 아키텍처 스타일에서는 찾아볼 수 없는 이 아키텍처의 특징이다.
15.4 복제 캐시 대 분산 캐시
공간 기반 아키텍처는 캐시 기술을 활용하여 애플리케이션 트랜잭션을 처리하고 데이터베이스에 직접 읽기/쓰기를 할 필요가 있어서 확장성, 탄력성, 성능이 우수하다.
대부분의 공간 기반 아키텍처는 복제 캐시도 사용할 수 있다.
15.5 니어 캐시
니어 캐시는 분산 캐시와 인 메모리 데이터 그리드를 접합한 일종의 하이브리드 캐시 모델이다.
15.7 아키텍처 특성 등급
공간 기반 아키텍처는 확장성, 탄력성, 성능의 끝판왕이다..!
이 아키텍처튼 인메모리 데이터 캐시를 활용하고 제약조건에 해당되는 데이터베이스를 없앴기 때문에 이 세가지 특성을 높은 수준으로 달성할 수 있다.
이러한 강점은 전체적인 단순성과 시험성 측면에서 트레이드 오프가 발생한다.
느낀점
진짜 제일 이해가 안된 것 같은 챕터…ㅠㅠ
논의 사항
없습니다..
16. 오케스트레이션 기반 서비스 지향 아키텍처 스타일
이름도 어렵네..
아키텍처 스타일은 예술 활동처럼 그것이 진화한 시대의 맥락에서 이해해야 한다.
16.1. 역사와 철학
서비스 지향 아키텍처는 1990년대 후반에 등장했고, 매우 빠른 속도로 성장했다.
하지만 이런 성장을 하드웨어 장비가 따라가지 못했기 때문에 가변적인 확장성, 다른 유용한 특성을 요구했다.
이 시대의 아키텍트들은 다양한 외부 여건 탓에 어쩔 수 없이 제약이 많은 분산 아키텍처를 구축했다.
오픈 소스 운영 체제를 프로덕션에서 사용해도 좋을 만큼 신뢰감을 얻기 전이었으므로 운영 체제는 많은 비용을 들여 시스템 단위로 라이센스를 구매했다.
사용법이 복잡
그 결과 아키텍트는 최대한 재사용하는 것을 목표로 삼게 되었고, 실제로 모든 형태의 재사용은 이 아키텍처의 중심 철학이 되었다.
16.2. 토폴로지
이 아키텍처 스타일은 아키텍트가 기술 분할에 집착하면 어떻게 되는지 잘 보여주는 사례이다.
아키텍처 내부에 서비스 택소노미를 정립하여 레이어별로 책임을 지운다는 아이디어는 동일하다.
서비스 지향 아키텍처는 분산 아키텍처이다. 분산 아키텍처는 조직마다 다양하다.
16.3. 택소노미
이 아키텍처의 중심 철학은 엔터프라이즈 레벨의 재사용이다.
16.3.1. 비즈니스 서비스
이 아키텍처 최상단에 위치한 비즈니스 서비스는 진입점 역할을 한다.
이 서비스 정의는 코드는 전혀 없고, 입력, 출력, 스키마 정보만 갖고 있다.
서비스는 대부분 비즈니스 유저가 정의하기 때문에 이름도 비즈니스 서비스이다.
16.3.2. 엔터프라이즈 서비스
엔터프라이즈 서비스는 세분화된 공유 구현체를 포함한다.
일반적으로 개발팀은 특정 비즈니스 도메인에 관한 원자적 행위를 구현하는 업무를 담당한다.
이런 서비스는 오케스트레이션 엔진을 통해 묶인, 단위가 큰 비즈니스 서비스를 구성하는 요소들이다.
이 아키텍처의 재사용 목표 때문에 이렇게 책임을 분리한 것이다.
개발자가 정확한 세분도에 맞게 서비스를 구축할 수 있다면 비즈니스 워크플로의 해당 파트를 재작성할 필요가 없기 때문..
그러나 현실에서는 실패했다.
16.3.3. 애플리케이션 서비스
아키텍처의 모든 서비스에서 엔터프라이즈 서비스와 동일한 레벨의 세분화 또는 재사용이 필요한 것은 아니다.
애플리케이션 서비스는 한 번만 사용 가능한 단일 구현체 서비스이다.
16.3.4. 인프라 서비스
인프라 서비스는 모니터링, 로깅, 인증/인가 등의 운영 관심사를 지원한다.
이런 서비스는 운영팀과 긴밀하게 협업하는 공유 인프라팀이 소유한 실질적인 구현체인 경우가 많다.
16.3.5. 오케스트레이션 엔진
오케스트레이션 엔진은 이 분산 아키텍처의 요체이다.
이 엔진은 비즈니스 서비스 구현체를 서로 엮어주며 트랜잭션 조정과 메시지 변환 등의 기능을 수행한다.
마이크로 서비스 아키텍처처럼 서비스마다 데이터베이스가 있는 것은 아니며, 일반적으로 단일 관계형 데이터 베이스를 사용한다.
따라서 트랜잭셔널 로직은 데이터베이스가 아닌 오케스트레이션 엔진에서 선언적으로 처리된다.
16.3.6 메시지 흐름
모든 요청은 오케스트레이션 엔진을 흘러간다.
16.4. 재사용… 그리고 커플링
이 아키텍처의 주된 목표는 서비스 레벨의 재사용, 즉 시간이 지남에 따라 재사용이 가능한 비즈니스 행위를 점직적으로 구축하는 능력이다.
16.5. 아키텍처 특성 등급
서비스 지향 아키텍처는 어쩌면 지금까지 시도된 아키텍처 중에서 가장 기술적으로 분할된 범용 아키텍처일 것이다.
모놀리식과 분산 아키텍처 모두의 단점을 갖고 있다.
느낀점
어떻게 보면 최고의 아키텍처를 만들려다 실패한 사례를 보여줌으로 트레이드 오프를 간과하지 말라는 말을 전하고 싶었던게 아닐까?
논의사항
없습니다..
17. 마이크로서비스 아키텍처 스타일
마이크로서비스는 최근 엄청난 탄력을 받고 있는, 아주 평판이 좋은 아키텍처 스타일이다.
이 장에선 토폴로지와 철학, 두 가지 관점으로 나누어 이 아키텍처의 중요한 특성을 개괄한다.
17.1. 역사
마틴 파울러와 제임스 루이스가 쓴 Microservices
라는 유명 블로그 게시글 덕분에 널리 퍼지게 되었다.
마이크로서비스는 소프트웨어 프로젝트의 논리적 설계 프로세스를 강조한 도메인 주도 설계(Domain-Driven Design, DDD)의 영향을 받았다.
특히, 디 커플링 스타일을 나타낸 경계 콘텍스트 개념은 마이크로서비스에 결정적인 영향을 미쳤다.
재사용은 유익하지만 커플링이 문제이다 (소프트웨어 아키텍처 제1법칙)
재사용을 선호하는 시스템을 설계하다 보면 결국 상속이나 조합을 이용하여 재사용하기 때문에 커플링이 발생한다.
그러나 고도의 디커플링이 아키텍트의 목표라면 재사용보다 중복을 우선할 것이다.
마이크로서비스의 주요 목표는 경계 콘텍스트의 논리적 개념을 물리적으로 모델링하는 고도의 디커플링이다.
17.2. 토폴로지
다른 분산 아키텍처에 비해 단일 목적만을 가지기 때문에 규모가 작다.
실제로 각 서비스에는 데이터베이스 및 기타 종속적인 컴포넌트 등 서비스가 독립적으로 작동되는데 필요한 모든 것이 준비되어 있다.
17.3. 분산
마이크로서비스는 분산 아키텍처를 형성한다.
빠르게 진화하며 물리적인 컴퓨터에서 컨테이너를 사용하게 되고 자주 발생하는 문제들을 해결할 수 있게 되었다.
17.4. 경계 콘텍스트
마이크로서비스의 근본 철학은 경게 콘텍스트 개념이다.
서비스마다 도메인이나 워크플로를 모델링하는 개념..!
마이크로서비스는 커플링을 가급적 삼가므로 이 아키텍처 스타일을 구축하는 아키텍트는 커플링보다는 차리리 중복이 낫다고 생각합니다.
17.4.1. 세분도
‘마이크로서비스’라는 용어는 명칭이지, 명세가 아니다.
마틴 파울러
목적: 가장 확실한 경계는 바로 이 아키텍처 스타일의 본래 의도인 도메인이다.
트랜잭션: 여러 엔티티가 함께 개입하여 작동되는 트랜잭션은 아키텍트에게 좋은 서비스 경계 후보입니다.
코레오그래피: 도메인 격리는 아주 잘 되어 있지만, 서로 광범위한 통신을 해야 제대로 작동되는 서비스 세트를 구축할 경우, 아키텍트는 통신 오버헤드를 줄이기 위해 더 큰 서비스로 다시 뭉치는 것을 고려해야 할 수도 있다.
좋은 서비스 설계안을 도출하는 유일한 방법은 이터레이션이다.
반복..!
17.4.2. 데이터 격리
마이크로서비스는 경계 콘텍스트를 기준으로 데이터를 격리해야 한다.
대부분의 다른 아키텍처는 데이터를 단일 데이터베이스에 저장하지만, 마이크로서비스 아키텍처는 통합 지점으로 사용되는 공유 스키마, 데이터베이스 등 모든 종류의 커플링을 없애려고 한다.
17.5. API 레이어
마이크로서비스 다이어그램을 보면 대부분 필수는 아니지만 여러 시스템 컨슈머 사이에 API 레이어가 있다.
API레이어는 다양한 용도로 활용될 수 있지만 이 아키텍처의 기본 철학에 충실하려면 API레이어를 중재자나 오케스트레이션 도구로 사용하지 말아야 한다.
모든 비즈니스 로직은 경계 콘텍스트 내부에서 일어나야 하며, 오케스트레이션 등의 다른 로직을 중재자에 넣는 것은 규칙 위반이다.
17.6. 운영 재사용
앞서 마이크로서비스가 커플링보다 복제를 선호한다고 했다.
전통적인 서비스 지향 아키텍처 철학에 따르면 도메인이든 운영이든 가급적 많은 기능을 재사용하는 것이 좋다.
- 사이드카 패턴
- 팀이 서로 커플링되면 더 유리한 모든 운영 관심사를 도맡아 처리한다.
- 각 마이크로서비스는 신기능을 받아 사용할 수 있다.
17.7. 프런트엔드
마이크로서비스는 디커플링을 선호한다.
유저 인터페이스와 백엔드 역시 분리되는 모습이 가장 좋다..!
마이크로 아키텍처의 유저 인터페이스는 보통 두 가지 스타일로 나뉜다.
- 모놀리식 프론트엔드
- 리치 테스크톱, 모바일, 웹 애플리케이션의 형태로 구현한다.
- 마이크로 프론트엔드
- 유저 인터페이스 레벨의 컴포넌트를 백엔드 서비스로 활용하여 유저 인터페이스를 동기적인 수준으로 세분화하고 격리한다.
17.8. 통신
마이크로서비스를 구축하는 아키텍트와 개발자는 데이터 격리와 통신 모두에 영향을 미치는 절절한 세분도를 찾고자 씨름한다.
올바른 통신 스타일을 발견하는 것 또한 팀이 서비스를 디 커플링하면서 유용한 방향으로 조정하는 데 도움이 된다.
아키텍트는 동기로 할지, 비동기로 할지. 근본적인 통신 방식을 결정해야 한다.
동기 통신은 호출부가 수신부의 응답을 기다린다.. 일반적으로 마이크로서비스 아키텍처는 프로토콜 인지 간 상호 운용성
- 프로토콜 인자: 마이크로서비스는 운영 커플링을 방지하고자 중앙 통합 허브를 갖고 있지 앟기 때문에 각 서비스는 다른 서비스를 호출하는 방법을 알고 있어야 한다.
- 이종: 마이크로서비스는 분산 아키텍처라서 각 서비스마다 구현 기술 스택이 상이할 수 있다. 이종이란, 서비스마다 사용하는 플랫폼이 저마다 다른 폴리그랏환경을 완벽하게 지원한다는 뜻
- 상호 운용성:여러 서비스가 서로 호출한다는 뜻
17.8.1. 코레오그래피와 오케스트레이션
코레오그래피는 브로커 이벤트 기반의 아키텍처와 통신 스타일이 동일하다.
즉, 이 아키텍처는 중앙의 중재자가 따로 없고 경계 콘텍스트 철학에 충실하다.
따라서 아키텍트는 서비스 간에 분리된 이벤트를 구현하는 것이 자연스럽다고 생각한다.
17.8.2. 트랜잭션과 사가
마이크로서비스 아키텍트는 극도로 디커플링을 갈망하지만 여러 서비스에 걸친 트랜잭션을 어떻게 조정하는 게 좋을지 고민하게 된다.
- 트랜잭션: 여러 서비스에 걸친 트랜잭션을 조정하는 것은 극도로 어렵다. 트랜잭션은 마이크로서비스 아키텍처의 철학과 맞지 않다.
마이크로서비스에 트랜잭션을 걸지 마세요. 대신 세분도를 바로잡으세요!
17.9. 아키텍처 특성 등급
전체 비용, 성능, 단순성을 제외하고 거의 만점이다.
느낀점
마이크로서비스에 대한 이미지가 조금 정리된..
논의사항
- 기억에 남는 부분: 마이크로서비스는 커플링을 가급적 삼가므로 이 아키텍처 스타일을 구축하는 아키텍트는 커플링보다는 차리리 중복이 낫다고 생각
커플링을 방지하기 위해서 차라리 중복이 낫다는 생각은 처음 들어보는 생각이라 신선했다..
18. 최악의 아키텍처 스타일 선정
매 챕터 마다 말하지만 최악, 최고의 아키텍처는 존재하지 않는다.
팀 by 팀, 프로젝트 by 프로젝트이머 다양한 트레이드 오프를 생각하여 아키텍처 스타일을 선택해야 한다.
18.1 아키텍처 ‘유행’은 계속 변한다
사람들이 좋아하는 아키텍처 스타일은 여러가지 팩터들로 인해 계속 변한다.
- 과거를 돌아본다.
- 생태계의 변화
- 새로운 기능
- 가속
- 도메인 변경
- 기술 변화
- 외부 팩터
18.2 결정 기준
아키텍트는 아키텍처 스타일을 선택할 때 도메인 설계 구조의 원인이 될 만한 모든 요소를 종합적으로 고려해야 한다.
기본적으로 아키텍트는 주어진 도메인, 그리고 시스템을 성공적으로 구축하는 데 필요한 다른 모든 구조적 요소들을 설계한다.
- 도메인
- 구조에 영향을 미치는 아키텍처 특성
- 데이터 아키텍처
- 조직 문제
- 프로세스, 팀, 운영 문제에 관한 지식
- 도메인/아키텍처 동형성
- 모놀리스냐 분산이냐
- 데이터를 어디에 둘것인지
- 서비스 간 통신은 동기 or 비동기
느낀점
최고, 최악은 없지만 최선은 있다.
논의사항
아키텍처가 결정되는 가장 큰 요인이 뭐라고 생각하시나요?
19. 아키텍처 결정
아키텍트에게 기대하는 핵심 가치 중 하나는 아키텍처 결정을 내리는 것이다.
아키텍처 결정은 애플리케이션이나 시스템의 구조에 관한 것이 대부분이지만 기술 결정 역시 (그것이 아키텍처 특성에 영향을 미칠 경우 ) 포함될 수 있다.
19.1 아키텍처 결정 안티패턴
아키텍처를 결정하는 것도 기술이다.
따라서 아키텍트가 결정을 내릴 때 아키텍처 안티패턴에 빠지지 않도록 주의해야 한다.
19.1.1 ‘네 패를 먼저 보여주지마’ 안티패턴
아키텍트가 잘못된 선택을 하는 것을 두려워한 나머지 아키텍처 결정을 회피하거나 미루는 현상을 말한다.
이 안티패턴은 두 가지 방법으로 극복할 수 있다.
- 어떤 중요한 아키텍처 결정을 내리기 전, 마지막으로 책임질 수 있는 순간까지 기다리는 것
- 개발팀과 지속적으로 협력하면서 아키텍트가 결정한 내용을 원래 의도한 대로 추진하는 것
19.1.2 ‘무한반복 회의’ 안티패턴
‘네 패를 먼저 보여주지마’ 안티패턴을 극복하면 이어서 ‘무한반복 회의’ 안티패턴으로 이어진다.
사람들이 어떤 결정을 왜 했는지 모르고 주구장창 회의만 계속 하는 것이다.
이 안티패턴이 발생하는 이유는 아키텍트가 자신이 내린 결정을 정당화하는데 실패했기 때문이다.
아키텍처를 정당화하려면 그 결정을 내리게 된 기술적, 비즈니스적 근거를 제시하는 것이 중요(따라서 앞에 나온 문서화도 중요하다.)
19.1.3 ‘이메일 기반 아키텍처’ 안티패턴
아키텍트가 아키텍처 결정을 하고 그 결정을 온전히 정당화한 다음은 ‘이메일 기반 아키텍처’ 안티패턴이 등장할 차례이다.
사람들이 아키텍처 결정을 놓치거나 잊어버리고 심지어 그렇게 결정됐다는 사실조차 알지 못해 아키텍처 결정을 구현하지 못하는 상태이다.
즉, 아키텍처 결정을 효과적으로 전달하는 문제와 관련된 안티패턴이다.
19.2 아키텍처적으로 중요한
아키텍처 결정에 기술적인 내용이 포함되면 그것은 아키텍처 결정이 아니라, 기술 결정이라고 단정짓는 아키텍트들이 많지만 반드시 그런 것은 아니다.
아키텍트가 어떤 기술을 사용하기로 결정 했고 그 기술을 어떤 아키텍처 특성을 직접 지원하기 위해 선택한 것이라면 그것은 아키텍처 결정이 맞다..!
19.3 아키텍처 결정 레코드
아키텍처 결정을 가장 효과적으로 문서화하는 방법은 바로 아키텍처 결정 레코드(ADR)이다.
19.3.1 기본 구조
ADR의 기본 구조는 제목, 상태, 콘텍스트, 결정, 결과, 이렇게 주요 5개 섹션으로 구성된다.
여기서 컴플라이언스와 노트라는 추가 센션을 덧붙인다.
필요시 센션을 추가하는 방법으로 기본구조를 확장하는 식으로 템플릿을 간명하게 유지할 수 있다.
다른 모든 대안의 분석 결과를 대안센션에 기록하는 것이 좋은 예이다.
19.3.2 ADR 저장
이렇게 공들여 작성한 ADR을 어디에 저장해야 할까?
일부 아키텍트들은 깃 레포에 보관하거나 위키에 저장하는 방법을 선호한다.
19.3.3 ADR로 문서화
소프트웨어 아키텍처의 문서화는 언제나 어려운 주제이다.
ADR은 소프트웨어 아키텍처를 효과적으로 문서화하는 수단으로 활용할 수 있다.
느낀점
아키텍트가 아키텍처를 선택하여 따라오는 책임을 깊게 생각해본적이 없는 것 같다.
생각보다 더 무거운 위치라는 생각..
논의사항
아키텍처 결정 안티패턴이 되게 말이 재밌었는데.. 프로그래머 레벨에서 안티패턴을 저런 형식으로 만들어 본다면 뭐가 있을까요..?
하하!
20. 아키텍처 리스크 분석
모든 아키텍처는 리스크를 가지고 있다.
(확장성, 가용성, 데이타 무결성에 문제는 없을까?)
아키텍처 리스크 분석은 아키텍트의 핵심 활동 중 하나로, 리스크를 꾸준히 분석하여 아키텍처의 내부 결함을 바로잡고 리스크를 줄이는 일이다.
20.1 리스크 매트릭스
아키텍처의 리스크를 평가할 때에는 먼저 리스크를 낮음, 중간, 높음 정도로 분류할지 결정해야 한다.
이런 분류 과정은 개인의 주관이 너무 많이 반영될 수밖에 없다.
리스크 매트릭스는 주관성을 낮추고 특정한 아키텍처 영역에서 리스크를 찾아내는데 도움이 된다.
20.2 리스크 평가
리스크 매트릭스를 활용하면 리스크 평가를 작성할 수 있다.
리스크 평가는 맥락에 따라 유의미한 평가 기준에 대해 전체 아키텍처 리스크를 요약한 리포트이다.
20.3 리스크 스토밍
시스템의 모든 리스크를 아키텍트 혼자 결정할 수는 없다.
리스크 스토밍은 특정 범위 내에 있는 아키텍처 리스크를 찾아내는 협력적인 활동이다.
일반적인 리스크 영역으로는 검증되지 않는 기술, 성능, 확장성, 가용성, 데이터 소실, 단일 장애 지점, 보안 등이 있다.
리스크 스토밍은 보통 여러 아키텍트가 참여하지만 선임 개발자와 기술 책임자도 동석하면 더 효과적이며, 개발자도 참여하면 구현 관점에서 아키텍처 리스크를 짚어볼 수 있으므로 아키텍처를 더 선명하게 이해할 수 있다.
리스크 스토밍은 전체 아키텍처는 물론, 아키텍트와 비즈니스 이해관계자들 간의 협상에도 리스크 스토밍은 상당한 영향을 미칠 수 있다.
20.4 애자일 스토리 리스크 분석
리스크 스토밍은 아키텍처는 물론, 다른 소프트웨어 개발 분야에도 응용할 수 있다.
느낀점
역시 학습과 개발은 혼자 쉽게 할 수 있는 것이 아닌 것 같다..
논의사항
실제 회사에서 아키텍처를 설계하거나 현재 아키텍처에 대해서 스토밍을 하는지..?
21. 아키텍처 도식화 및 프레젠테이션
아키텍처를 도식화하고 프레젠테이션하는 일은 아키텍트의 두 가지 핵심 소프트 스킬이다.
사용하는 매체는 다르지만 아키텍처 버전의 중요한 부분을 시각적으로 나타낸다는 공통점이 존재한다.
표현의 일관성
21.1 도식화
아키텍처 토폴로지는 아키텍트와 개발자가 늘 관심있어 하는 분야로 구조가 어떻게 맞물리는지 알아야 팀간의 공통된 이해를 형성할 수 있다.
따라서 아키텍트는 언제나 다이어그램을 작성하는 기술을 갈고 닦아야 한다.
21.1.1 도구
요즘의 다이어그램 도구는 매우 강력한 편이다.
아키텍트는 자신이 사용하는 도구를 철저하게 학습하는 것이 중요하다.
도구도 도구지만 정확도가 떨어지는 아티팩트를 간과해선 안된다.
무리한 아티팩트 집착
무리한 아티팩트 집착은 어떤 아티팩트에 대한 한 사람의 무분별한 집착과 그 아티팩트의 개발 시간 사이의 비례 관계를 말한다.
가능한 한 절차를 간소하하여 적시에 아티팩트를 만드는 방식은 애자일 소프트웨어 개발 방법론의 강점 중 하나이다.
기술 의존도가 낮은 도구를 사용하면 팀원들이 옳지 않은 것은 버리고 자유롭게 실험, 개선, 협력, 토론함으로써 아티팩트의 진정한 특성을 발현시킬 수 있다.
레이어
다이어그램 도구는 대부분 레이어를 지원한다.
레이어를 사용하면 작성자가 여러 항목을 논리적으로 연결해서 각각의 레이어로 만들어 숨김/표시할 수 있고 굳이 필요하지 않은 부분은 가릴 수 있다.
스텐실/템플릿
스텐실을 사용하면 보통 다른 기본 셰이프를 조합한, 자주 쓰이는 시각 컴포넌트를 라이브러리화할 수 있다.
마그넷
마그넷은 선을 자동으로 연결/정렬하는 기능으로, 셰이프를 쉽게 그릴 수 있게 해주고 시각적인 효과도 제공한다.
21.1.2 도식화 표준: UML, C4, ArchiMate
소프트웨어 기술 다이어그램은 몇 가지 공식적인 표준이 제정되어 있습니다.
UML
통합 모델링 언어(Unified Modeling Language, UML)는 한 때는 소프트웨어 개발의 표준이었지만, 요즘은 다른 표준들이 UML을 대체하고 있다.
C4
C4는 UML의 결함을 보완하고 보다 현대적인 방식으로 접근하고자 사이먼 브라운이 개발한 다이어그램 기법이다.
C4에서 C
4개는 다음을 의미한다.
- Context: 유저 역할, 외부 의존성 등 시스템의 전체 콘텍스트
- Container: 아키텍처 내부의 물리적 배포 경계 및 컨테이너, 이 뷰는 운영자와 아키텍트의 훌륭한 접점을 형성한다.
- Component: 시스템의 컴포넌트 뷰, 대부분의 아키텍트가 시스템을 바라보는 관점과 거의 일치
- Class: C4는 UML과 동일한 스타일의 클래스 다이어그램을 사용하는데, 이 클래스 다이어그램은 그 자체로 효과적이어서 굳이 교체할 필요가 없다.
C4는 컨테이너와 컴포넌트의 관계가 달라질 수 있는 모놀리식 아키텍처에 가장 적합하며, 마이크로서비스 같은 분산 아키텍처와는 잘 맞지 않는다.
ArchiMate
ArchiMate는 비즈니스 도메인을 중심으로 아키텍처를 기술, 분석, 시각화하는 오픈소스 엔터프라이즈 아키텍처 모델링 언어이다.
모든 엣지 케이스를 다루는 게 아닌 가능한 적게 만들자..!
21.1.3 도식화 지침
자신만의 모델링 언어를 사용하든, 공식적인 언어를 사용하든, 아키텍트는 다이어그램을 그리는 자신의 스타일을 구축하고 스스로 효과적이라고 생각한 프레젠테이션에서 자유롭게 다이어그램을 빌려 써야 한다.
제목
다이어그램의 모든 앨리먼트에 청중이 쉽게 알아볼 수 잇도록 제목을 붙인다.
선
선은 어느정도 굵어야 눈에잘 들어온다.
정보의 흐름을 나타내는 선은 화살표를 이용해 트래픽 방향을 표시한다.
화살표 머리는 종류마다 의미가 다를 수 있으니 일관성있게 사용한다.
동기통신은 실선, 비동기 통신은 점선으로 나타내는 것은, 아키텍처 다이어그램에서 몇 안 되는 표준이다.
셰이프
정규 모델링 언어는 표준 셰이프를 모두 기술하지만, 소프트웨어 개발 업계 전체에서 통용되는 표준 셰이프는 따로 없다.
따라서 아키텍트는 자신의 표준 셰이프 세트를 만들고 필요시 조직 전체에 전파하여 일종의 표준 언어를 만든다.
레이블
다이어그램 항목마다 레이블을 붙인다.
보는 사람 입장에서 모호한 항목은 반드시 레이블로 구분한다.
색상
색상은 흑백을 가장 많이 사용하지만 구분하기 위해 색상을 사용하면 좋다.
키
어떤 이유로든 셰이프가 모호하다면 다이어그램에 키를 넣어서 셰이프가 가리키는 것을 명확하게 밝히는 것이 좋다.
21.2 프레젠테이션
프레젠테이션은 아키텍트가 갖춰야할 또 다른 소프트 스킬이다.
21.2.1 시간 조작
프레젠테이션 도구는 전환과 애니메이션으로 시간을 조작한다.
이러한 기능을 사용해 슬라이드 간 경계를 감춰서 한 슬라이드에 다 담는 것이 아닌 여러 슬라이드를 사용하여 이야기를 보여줄 수 있다.
21.2.2 점진적 빌드
프레젠테이션을 하는 발표자는 구두와 시각, 2개의 정보 채널을 갖고 있다.
슬라이드를 과도한 텍스트로 채워 넣고 그것을 그냥 소리내어 읽는 것은 한쪽 정보 채널에는 과부하를 걸고 다른쪽 채널은 굶주리게 하는 셈이다.
따라서 이런 문제를 해결하기 위해선 슬라이드를 점진적으로 빌드함으로써 한 번에 전부가 아니라 필요한 만큼의 정보만 쌓아 올려야 한다.
21.2.3 인포덱스 vs 프레젠테이션
인포덱스는 참석자가 잡지와 같이 슬라이드 덱을 각자 페이스에 맞게 읽는 것이다.
인포덱스와 프레젠테이션, 두 매체의 차이점은 콘텐츠 종합성과 전환/애니메이션 효과의 사용이다.
21.2.4 슬라이드는 절반의 스토리
발표자가 가장 많이 하는 실수는 프레젠테이션의 전체 콘텐츠를 슬라이드로 만들어버리는 것이다.
슬라이드 내용이 뭔가 포괄적인 경우에는 모든 청중이 끝까지 프레젠테이션을 앉아서 지켜보느라 시간을 낭비하지 않도록 슬라이드 덱을 모두에게 이메일로 보내는 것이 좋다.
21.2.5 불가시성
불가시성은 청중이 발표자에게만 주목하도록 프레젠테이션에 빈 검정 슬라이드를 삽입하는 정말 단순한 패턴이다.
느낀점
도식화와 프레젠테이션은 아키텍트에게 필요한 부분이라고 본다.
새로운 도식화 도구에 대해서도 알게되고 알고 있지만 몰랐던 용어도 정리된 것 같아서 나름 좋았다.
프레젠테이션또한 어렴풋이 알고 있었지만 용어로 정리된 내용을 읽어서 도움이 될 것 같다
논의사항
실제 현업에서 사용 또는 많이 본 도식화는 어떤 것이 있을까요?
22. 개발팀을 효율적으로
소프트웨어 아키텍트는 기술 아키텍처를 정립하고 아키텍처 결정을 내릴 뿐만 아니라, 개발팀이 아키텍처를 올바르게 구현하도록 안내할 책임이 있다.
팀을 생산적으로 만드는 능력은, 유능하고 성공적인 소프트웨어 아키텍트가 다른 아키텍트들과 차별화되는 강점이다.
22.1 팀 경계
스스로 정상 궤도에서 벗어났거나 소프트웨어 아키텍트로부터 멀어졌다고 느끼는 개발팀은 대부분 시스템의 다양한 제약조건을 제대로 알지 못하고 경험도 없기 때문에 아키텍처를 올바르게 구현하지 못한다.
따라서 소프트웨어 아키텍처가 필요하다.. 아키텍트는 개발자가 아키텍처를 구현할 수 있게 제약조건이나 어떤 틀을 만들어 개발팀과 소통하는 일을 한다.
아키텍트는 너무 빡빡하거나, 너무 느슨하거나, 얼추 딱 맞는 경계를 생성할 수 있는데 이는 팀의 능력에 직접적인 영향을 미친다.
아키텍트가 제약조건을 너무 많이 설정하거나 너무 느슨하게 설정할 경우엔 개발자들이 아키텍처를 구현하는데 어려움을 겪는다.
유능한 아키텍트는 팀의 경계를 적당하게 설정하여 올바른 도구와 라이브러리로 무장하여 아키텍처를 잘 구현할 수 있더록 적절한 지침과 제약조건을 제공한다.
22.2 아키텍트 성향
아키텍트의 성향은 내 마음대로 아키텍트
, 유체이탈 아키텍트
, 유능한 아키텍트
세 가지 정도로 나뉜다.
이 세 타입은 앞 절에서 설명한 팀 경계를 설명하면서 분류한 경계 타입과 정확하게 일치한다.
22.2.1 내 마음대로 아키텍트
내 마음대로 아키텍트는 소프트웨어 개발 프로세스의 세세한 부분을 일일이 통제하려고 한다.
이런 아키텍트가 내리는 결정은 하나같이 세부적으로 저수준에 관한 내용이라서 개발팀에 과도한 제약을 초래한다.
경계가 아주 빡빡하기에 개발팀이 알아서 쓸 만한 오픈소스나 서드파티 라이브러리를 마음대로 사용하지도 못하고 컨벤션부터 의사코드까지 모든 것을 아키텍트가 정해버린다.
개발자에서 아키텍트로 전직한 경우 많이 발생
아키텍트는 프로젝트의 복잡성과 팀 기술 수준에 따라 내 맘대로 아키텍트라는 악역을 맏아야 할 때도 있다.
그러나 대개 내 맘대로 아키텍트는 개발팀을 혼란에 빠뜨리고, 적절하게 지도하지 못한 채 외려 방해가 될 때도 많고, 팀을 이끌어 아키텍처 구현을 리드하는 데 적합하지 않은 편이다.
22.2.2 유체이탈 아키텍트
유체이탈 아키텍트는 꽤 오랫동안 코딩을 한 적이 없어서 아키텍처를 수립할 때 세부 구현 사항은 거의 나몰라라 하는 아키텍트이다.
기술 또는 비즈니스 관점에서 유체이탈 아키텍트는 그냥 머리가 꽉 막힌 사람들이므로 팀을 리드하거나 가이드하는 일을 애당초 불가능하다.
결국 개발팀이 스스로 아키텍트 역할을 맡아 아키텍트가 할 일을 대신 하게 되는데 진척도와 생선성이 떨어지는 것은 물론, 팀원들이 시스템 작동 방식을 이해하는 과정에서도 혼란에 빠지게 된다.
22.2.3 유능한 아키텍트
유능한 아키텍트는 개발팀에 적절한 제약조건과 경계를 설정하고 팀원들이 서로 잘 협력할 수 있도록 독려하며 그들을 올바른 수준으로 가이드해야 한다.
당연하게 보일 수 있지만 결코 쉽지 않다.
개발팀을 잘 이끄는 유능한 리더가 되는 것은 일종의 예술이다.
22.3 얼마나 제어해야 하나?
팀원 간 친밀도
팀원들이 서로 잘 아는 사이라면 이미 스스로 조직화하기 시작되므로 제어가 덜 필요하고, 그 반대일수록 팀원 간 협업을 촉진하고 팀 내 파벌을 없애기 위해 더 많은 제어가 필요하다.
팀 규모
팀이 커질수록 더 많은 제어가 필요하고, 팀이 작을수록 제어가 덜 필요하다.
전체적인 경험
주니어 개발자가 많은 팀은 제어와 멘토링이 더 필요하고, 시니어 개발자가 더 많은 팀은 아무래도 제어가 덜 필요하다.
프로젝트 복잡도
복잡도가 높은 프로젝트를 수행하려면 아키텍트가 팀에 더 많이 관여하여 갖가지 이슈를 처리해야 할 테니 팀에 더 많은 제어를 가할 수밖에 없다.
프로젝트 기간
프로젝트 기간이 더 길수록 더 많은 제어가 필요하고 짧을수록 덜 필요하다.
22.4 팀의 이상 징후
팀 규모는 아키텍트가 개발팀에 행사하는 제어량에 영향을 미치는 팩터 중 하나이다.
팀이 클수록 제어가 더 많이 필요하고, 팀이 작을수록 제어가 덜 필요하다.
가장 효율적인 개발팀의 규모는 다음 세 가지 팩터에 의해 결정된다.
- 프로세스 손실
- 다원적 무지
- 책임 확산
프로세스 손실
기본적으로 프로젝트에 인력을 더 많이 투입할수록 프로젝트 수행하는 시간이 더 길어진다는 것을 의미한다.
그룹 포텐셜은 팀원 모두의 집합적인 노력에 의해 정의되지만 어느 팀이건 실제 생산성은 이 그룹 퍼텐셜에 훨씬 못 미친다.
유능한 아키텍트는 개발팀을 잘 관리하여 프로세스 손실을 찾는다.
만약 병합 충돌이 자주 발생한다면 프로세스 손실의 징후라고 볼 수 있다.
즉, 팀원들이 서로의 발을 밟은 채 동일한 코드 작업을 하고 있다는 방증이다.
다원적 무지
팀 규모가 너무 커지면 다원적 무지 현상이 발생한다.
모든 사람들이 자신이 뭔가 너무 뻔한 것을 놓치고 있는 게 아닐까 두려운 나머지 어떤 표준에 순순히 동의하는 현상이다.
자칫 말을 잘못 꺼냈다가 이렇게 뻔한 거도 모르냐 등등..
유능한 아키텍트는 회의나 토론을 하더라도 상대방의 생각과 몸짓을 읽고 조정자를 자처해야 한다.
의견을 물어보고 그들의 편을 지지해야 한다.
책임 확산
팀 규모가 커질수록 의사 소통이 잘 안되는 건 모두가 공감하는 팩트이다.
팀원 중 누가 무슨 일을 담당하고 있는지 혼란스럽다면 팀이 너무 커졌다는 신호이다.
유능한 아키텍트는 개발팀이 아키텍처를 잘 구현하도록 친절하게 안내하는 것은 물론, 팀이 건강하고 행복하게 공동 목표를 달성하도록 서로 협력하는 분위기를 조성해야 한다.
22.5 체크리스트 활용
체크리스트에 적합한 프로세스는 순서나 종속된 작업이 없는 프로세스, 그리고 에러가 발생하기 쉽거나 누락되어 다음으로 넘어가기 쉬운 단계가 있는 프로세스이다.
체크리스트를 효과적으로 작성하는 핵심 요령은, 만사를 체크리스트하려고 무리하지 말고 모든 단계를 포착하되 가능한 체크리스트는 최소화하는 게 좋다.
가장 효과적이라 생각되는 체크리스트는 개발자 코드 완료, 단위/기능 테스트, 소프트웨어 릴리스 체크리스트이다.
22.5.1 개발자 코드 완성도 체크리스트
개발자 코드 완성도 체크리스트는 소프트웨어 개발자가 코드를 완료
했다고 말할 때 사용하기 좋은 도구이다.
완료된 것의 정의
를 할 때에도 유용하다.
개발자가 이 체크리스트의 모든 항목을 완료했다면 실제로 코딩을 완료했다고 봐도 된다.
22.5.2 단위/기능 테스트 체크리스트
단위/기능 테스트 체크리스트는 가장 효과적인 체크리스트 중 하나이다.
대다수의 개발자가 테스트를 잊기 쉬운, 다소 특이한 엣지 케이스 테스트가 들어 있다.
QA팀 사람들은 어떤 테스트 케이스에서 이슈를 발견할 때마다 이 체크리스트에 추가한다.
22.5.3 소프트웨어 릴리스 체크리스트
소프트웨어를 프로덕션에 릴리스하는 작업은 소프트웨어 개발 라이프 사이클에서 가장 에러가 발생하기 쉬운 부분이므로 체크리스트를 작성하면 도움이 된다.
빌드 및 배포 실패를 예방하는 데에도 탁월한 효능이 있고 소프트웨어 출시 관련 리스크도 크게 줄어든다.
22.6 지침 제시
소프트웨어 아키텍트는 설계 원칙을 적용하고 지침을 제공하여 팀을 효과적으로 만들 수 있다.
특수한 목적
PDF 렌더링, 바코드 스캐닝등 딱히 커스틈 소프트웨어를 작성할 만한 이유가 없는 상황에서 사용되는 특수한 라이브러리
일반적인 목적
자바 진영의 아파치 커먼스, 구아바처럼 언어 API를 감싼 래퍼
플레임워크
퍼시스턴스, 제어 역전등에 사용하는 라이브러리
이렇게 범주화한 다음 이 설계 원칙을 중심으로 틀을 만든다.
아키텍트가 특정한 목적에 맞는 라이브러리를 지정하면 개발자는 그 라이브러리에 대해서만큼은 아키텍트의 조언을 따로 구할 필요없이 스스로 판단할 수 있다.
22.7 마치며
개발팀을 잘 굴러가게 만들기란 참으로 어렵다.
많은 경험과 연습이 필요하고 강력한 대인 관계 기술이 필요하다.
소프트웨어 아키텍트는 팀을 기술적으로 이끌 뿐만 아니라 아키텍처 구현을 통해 팀을 리드한다.
소프트웨어 아키텍트는 개발팀과 긴밀한 협력 관계를 유지하면서 팀 역학을 관찰하고 변경을 촉진하여 효과적으로 팀을 움직일 수 있다.
이것이 바로 기술만 가진 아키텍트와 유능한 소프트웨어 아키텍트를 구분하는 잣대이기도 하다.
느낀점
아키텍트로써 바라봐야한 개발팀도 있지만 실제 개발팀이 만들어지고 거기서 오는 문제들을 알아볼 수 있어서 좋았다.
내용자체가 실리콘 밸리의 팀장들
과 비슷하다는 생각이 드는게 당연한 것 같다.
논의사항
회사 규모로 보면 개발팀의 규모가 엄청 클텐데 책에서 나오는 팀 이상징후들을 어떻게 관리하는지 궁금합니다.
23. 협상과 리더십 스킬
협상과 리더십은 습득하기 어려운 스킬이다.
유능한 아키텍트가 되려면 오랜 기간에 걸쳐 학습, 실습, 그리고 산 지식
을 체득해야 한다.
23.1 협상과 조정
이 능력이 중요한 이유는 소프트웨어 아키텍트가 내리는 거의 모든 결정이 곳곳에선 거친 도전과 반대에 부딪히기 때문이다.
협상은 소프트웨어 아키텍트가 지녀야 할 가장 중요한 스킬 중 하나이다.
유능한 소프트웨어 아키텍트는 사내 정치를 잘 이해하고 강력한 협상 및 조정 능력을 발휘하며, 모든 이해관계자들이 동의하는 해법을 찾는 과정에서 맞닥뜨리는 숱한 의견 차이를 극복할 것이다.
23.2 소프트웨어 아키텍트는 리더다
소프트웨어 아키텍트는 개발팀을 이끌고 아키텍처를 구현하는 리더이다.
유능한 아키텍트가 되는 50% 정도는 효과적인 대인 관계 스킬, 조정 능력, 리더십에 있다고 생각합니다.
이 절에서는 유능한 소프트웨어 아키텍트로서 개발팀을 이끌어가는 데 기억해야 할 몇 가지 중요한 리더십 스킬을 소개한다.
23.2.1 아키텍처 4C
개발자는 나방이 불빛에 끌리듯 복잡한 것에 이끌린다. 결과는 대부분 똑같다.
우발성 복잡성을 방지하는 가장 좋은 방법은 아키텍처 4C를 따르는 것이다.
커뮤니케이션, 협동, 명료함, 간결함을 실천하는 것
23.2.2 실용적으로 행동하되 비전을 가져라
유능한 소프트웨어 아키텍트는 실용적이면서 동시에 비전을 가져야 한다.
이것은 말보다 실천이 쉽지 않아 매우 높은 수준의 성숙도와 꾸준한 연습을 필요로 한다.
비전을 가진다: 상상력이나 지혜를 발휘하여 미래를 떠올리거나 계획한다.
즉, 비전을 가진다는 것은 어떤 문제를 전략적 사고 방식으로 접근한다는 뜻이다.
실용적이다: 이론적으로만 생각하지 않고 실제에 근거한 방식으로, 분별 있게, 현실적으로 일처리한다.
아키텍트는 비전을 가져야 하지만 현실적인 솔루션을 적용해야 한다.
- 예산 제약 등의 비용 요소
- 시간 제약 등의 시간 요소
- 개발팀의 스킬 세트 및 수준
- 아키텍처 결정에 관한 트레이드오프와 의미
- 제안된 아키텍처 설계 또는 솔루션의 기술적인 한계
아키텍트로서 존중받으려면 실용적인 것과 비전을 가지는 것의 균형을 잘 맞추는 게 중요하다.
비즈니스 이해관계자는 갖가지 제약 조건에 적합한, 비전이 가미된 솔루션을 높이 평가하고, 개발자는 구현 관점에서 솔루션이 실용적이라는 사실에 더 후한 점수를 줄 것이다.
23.2.3 모법을 보여 팀을 리드하라
계급이 아닌 모법을 보여 리드하라
사람들을 이끌 때 계급과 직책은 별로 의미가 없다.
문제가 무엇이든지 결국 사람이 문제
기본적으로 존경심을 자아내고 팀을 이끌어 가는 것은 인간 관계 기술이다.
“~해야합니다.”, “당신이 해야할 일은 ~”식의 말투는 자신의 의견을 강요하는 것으로 협업 자체를 중단 시켜버린다.
사실 이건 협업이 아니라 일방적인 통보일뿐이다.
“~를 고려해보신적 있나요?”, “~는 어떨까요?”같은 표현에 주목한다.
질문을 던짐으로 개발자나 클라이언트에게 제어권을 내주고 아키텍트와 개발자가 함께 솔루션을 만들어가는 협업 대화가 이어진다.
이런 분위기를 조성하려면 구사하는 어법이 매우매우 중요하다.
아키텍트와 개발팀의 상호 존중 및 건전한 관계를 형성하는 또 다른 기술은 이름을 부르는 것이다.
이름을 부르며 악수를 하면서 눈을 맞추는 것은 기본적인 신뢰를 쌓는 방법이다.
브라운 백 미팅
22.3 개발팀과의 융합
아키텍트의 캘린더는 대부분 회의로 가득 차 있다.
그렇다면 언제 개발팀과 만나 협의하고 안내하고, 멘토링을 해야할까?
안타깝지만 IT세계에서 회의는 필요악이다. 회의는 항상, 그리고 자주 일어나기 마련이다.
유능한 소프트웨어 아키텍트로서 성공하는 핵심 포인트 중 하나는, 개발팀에 더 많은 시간을 할애하는 것이다.
회의 시간을 스스로 제어하여 시간을 낭비하지말고 개발팀과 시간을 보내야 한다.
마치며
협상과 리더십 팁은 소프트웨어 아키텍트가 개발팀과 그 밖의 이해관계자들과 더 나은 협력 관계를 구축하는 데 큰 도움이 될 것이다.
유능한 소프트웨어 아키텍트가 되려면 반드시 갖추어야 할 필요 기술이자, 효과적인 리더가 되는 첫 여정을 시작하기 좋은 팁이다.
성공의 공식에서 가장 중요한 한 가지 성분은 다른 사람들과 잘 지내는 방법을 아는 것이다.
느낀점
마찬가지로 실리콘 밸리의 팀장들
의 의사소통 방법이라든지 리더십에 관한 내용이 많았다.
논의사항
자신만의 신뢰관계를 형성하기 위한 스킬이 있나요?
24. 커리어패스 개발
아키텍트가 되고 난 이후의 커리어 패스
아키텍트는 커리어 내내 끊임없이 배워야 한다.
기술 세계는 현기증이 날 정도로 변화가 빠르다.
24.1 20분 규칙
아키텍트는 기술의 깊이보다 기술의 폭이 더 중요하고 이 폭을 유지하려면 시간과 노력이 필요하다.
하지만 대부분 회사를 다니며 시간을 할애하기 때문에 커리어 개발에 힘을 쓰는 이는 매우 적다.
이러한 균형을 유지하는 기술로 20분 규칙이 있다.
아키텍트로서 커리어를 유지하기 위해 새로운 것을 배우거나 특정 주제를 깊이 파고드는 시간을 매일 최소 20분은 할애하라는 규칙이다.
하루가 시작될 때 가장 먼저 실천하는 것이 좋다.
24.2 개인 레이더 개발
개발자에게 필요한 것은 기술 레이더이다.
기존 기술과 초기 기술의 리스크와 보상을 평가하는 살아있는 문서를 말한다.
24.2.1 쏘우트윅스 기술 레이더
책을 읽거나 컨퍼런스에 참여하여 최신 동향을 알아가는 것이 좋다.
24.3 소셜 미디어 활용
한 사람이 다른 사람과 접촉하는 네트워크는 3가지 범주로 나뉜다.
첫째, 강한 인맥은 가족, 동료, 그리고 개인적으로 계속 연락하고 지내는 사람들이다.
둘째, 약한 인맥은 주변의 지인, 먼 친척, 그리고 일년에 몇 번 볼까말까한 사람들이다.
셋째, 잠재적 인맥은 아직 만나지 않은 사람들이다.
어떤 사람의 다음 일자리는 강한 인맥보다 외려 약한 인맥에서 창출될 가능성이 더 높다는 점이다.
강한 인맥에 속한 사람들은 언제나 가까이 지내는 터라 서로에 대해 많은 걸 알고 있지만, 약한 인맥의 사람들은 새로운 잡 포지션 등 그 사람의 일반적인 경험에서 비롯된 조언을 해줄 수 있다.
아키텍트는 소셜 미디어, 소셜 네트워크의 특성을 잘 활용해서 기술 폭을 넓힐 수 있다.
트위터 같은 소셜 미디어를 전문적으로 활용해서 기술의 폭을 넓힐 수 있다.
24.4 종언
어떻게 해야 좋은 설계자를 얻을 수 있을까요? 물론 설계는 좋은 설계자가 하는 것입니다.
그럼 훌룡한 아키텍트를 구하려면 어떡해야 하나요? 한 사람의 커리어에서 아키텍트가 될 기회라곤 다 해봐야 6번도 안 될 텐데요?
아키텍처는 물론 삶의 모든 것에서 더 나은 사람으로 거듭날 수 있는 가장 검증된 방법은 바로 연습이다.
아키텍처에는 정답도 오답도 없다. 오직 트레이드오프만 있을 뿐
느낀점
아키텍처도 마찬가지이지만 개발자로서도 가져야하는 마음가짐인 것 같다.
나는 TODO에 미디엄 개발관련 글을 하루에 무조건 30분은 읽고 있다.
논의사항
- 스스로 기술의 폭을 넓히기 위해 어떤 노력을 하고 있나요?
댓글남기기