ArchitectureDesign

아키텍처와 설계

·17 min read

새삼스럽지만, 글 쓰는건 너무 어렵다.

특히나 매일 쓰는건 더욱이나 어려운 일이다.

요 근래 글을 약간 지식 정리하는 용도로만 쓰지,

그 지식을 체화하는 용도로 못쓰고 있는 거 같다고 느꼈다.

그저 급하게 매일 일기를 채운다는 느낌으로 쓰게 되니 그런 거 같다.

아무튼 오늘은 좀 더 자유로은 느낌으로 글을 쓰고자 한다.

오늘은 도서 '헤드 퍼스트 소프트웨어 아키텍처'에서 나오는 아키텍처와 설계의 차이에 대해서 다뤄보고자 한다.

소프트웨어 아키텍처

설계와의 차이를 논하기 전에 먼저 소프트웨어 아키텍처부터 알아보자.

일단 설계도라고 생각하자.

유래를 따지자면 건축쪽이니깐 건축을 예시로 들어보겠다.

집도 처음에 지을 때는 종이에다가 2D로 도식화해서 그려둔다.

우리도 서비스 몇달에 걸쳐서 만들어놨는데, 막상 다이어그램으로 그려두면 한페이지에 담긴다.

복잡한 시스템을 가장 중요한 가치(차원)으로 구분하여 구조를 만드는 과정을 생각하면 된다.

아키텍처의 차원들

건축 관점에서 설계도에 중요한 가치(차원)는 높이, 길이, 너비 등이 있을 것이다.

건축의 설계도란 공간적인 가치가 가장 중요하기 때문이다.

소프트웨어 아키텍처는 차원을 4가지로 나눌 수 있다.

  1. 아키텍처 특성: 확장성, 가용성 등 지원해야하는 시스템적 특성들

  2. 아키텍처 결정: 장기적인 시스템 운용에 상당한 시사점을 가지는 아주 중요한 결정들

  3. 논리적 컴포넌트: 시스템 구성 요소들과 서로 어떻게 상호작용 하는지에 대한 설명

  4. 아키텍처 스타일: 시스템의 물리적 구조와 형태 등

차원을 나눈다 해도 각각의 요소는 서로 연결되어있다.

특성에서 갑작스런 부하를 견디는 가용성이 필요하다고 하면,

어떻게 가용성을 조달할 것인가 중대한 결정을 내린다.

결정에 따라서 논리적 컴포넌트 구성이 바뀌고

물리적 서버가 분리될 수 있고, 가용성에 치중된 형태로 바뀔 수 있다.

바쁘다고 일부 차원을 생략하는 것은

"우리는 마이크로 서비스를 만들거에요" 했지만

정작 뭘 만들지는 상상에 나래에 맡기는 것과 같다.

아키텍처 특성

시스템 아키텍처의 기반이다.

어떤 문제를 해결할 것인가, 어떤 목적에 치중할 것인가 와 같은 현실적인 제약과 연관이 있기도 하다.

성능, 가용성, 확장성 등의 속성에서 어떤 부분에 좀 더 집중할 것인가를 선택하는 과정이기도 하다.

예를 들면, 데이터 베이스 선택 과정에서

데이터베이스 선택 과정에서 고성능의 검색이 필요한가? => 성능

데이터의 관계를 유지해야하는가? => 무결성

과 같이 목적에 따라서 특성의 비중이 달라진다.

비중이 달라진다는 점에서 이 단계에서 알 수 있는 것은 바로 트레이드오프다.

(vs 게임, 성능 아니면 안정성?)

아키텍처 결정

시스템 구조적 측면에서 우리가 내린 결정들이다.

단순한 결정이 아닌, 장기적으로 중요한 영향을 미치는지가 포인트다.

보통 우리는 서버 만들고 DB 바로 접근을 하는데,

어쩌면 중간에 DB 접근 서비스를 따로 만들 수 있다.

외냐고? 그건 특성따라 다르다.

굳이 하나 시나리오 들자면

확장성 고려와 기존 레거시 시스템 지원을 위해 여러 DB 종류에 연결하다보니 서버에 DB 로직 비중이 높아지면서,

트레이트 오프를 고려해보니깐 분리를 해서 복잡도를 낮추는게 더 나은 선택이다...

라고 소설을 써볼 수 있겠다.(개발의 세계 무엇이든 일어날 수 있다)

논리적 컴포넌트

특수한 목적이 있거나 변태같은 취향이 있는게 아니라면 어느정도 소스 코드에 대한 구조를 만들어놨을 것이다.

src나 app 폴더가 상위에 있고,

아래로는 database, core, api 등등 목적에 따라서 폴더가 분류되어 있을 것이다.

논리적 컴포넌트란 처리하고자 하는 목적에 따라 나뉘어진 논리적 구조라고 보면 된다.

보통 논리적 구조랑 물리적 파일 시스템이랑 같이 움직이다 보니 파일 시스템을 기준으로 말했다.

도식화 하자면

주문 배치 => 결제 처리 => 주문 발송...

이라는 컴포넌트가 있을 때

결제 처리는 app/order/payment 폴더 하위에 여러가지 소스코드가 있지 않을까

아키텍처 스타일

시스템을 만들 때 선택 가능한 구조가 다양하다.

마이크로 서비스, 레이어드, 이벤트 기반 등등

저마다의 목적과 특성을 가진 구조들이 존재한다.

어떤 구조를 선택하느냐에 따라 지원하는 특성이 다를 것이고,

시스템 전반적인 영역에 영향을 끼치며 다른 구조로 변환이 매우 어렵기에 중요한 결정 단게가 된다.

보통은 특성, 결정 단계에서 논의되면서 어떠한 구조를 가져갈 것인가에 단계에서 스타일을 선택하는데,

그렇다고 순서 따져서 거의 마지막 부분에 결정되는 사항은 아니다.

각 차원은 서로 연결되어 있기에 특성과 결정, 구조에 따른 트레이드 오프를 복잡하게 논의해가며 다각적으로 가져갈 것이다.

아키텍처와 설계

어떤 구조로 어떻게 만들꺼에요? 라고 생각하니 설계랑 비슷할 수 있는데,

여기서 설계는 좀 더 작은 범위이다.

아키텍처가 구조적인 부분을 논한다면, 설계는 그 안에 세부적인 구현이다.

아키텍처가 프론트가 서버랑 어떻게 통신하고, DB랑 연결되는 구조를 논한다면

설계는 구현할 때 어떤 라이브러리 가져다 썼는지, 디자인 패턴 뭐 했는지 같은 안을 봐야 보이는 외관적인 측면이다.

'구조'와 '외관'의 차이가 있는 것이다.

설계 관점

설계와 밀접한 연관이 있는게 바로 UML 클래스 다이어그램일 것이다.

주문이 있고, 결제가 있는데 결제 모듈은 현금도 되고 카드도 된다 라는 구현이 있을 때,

주문과 결재 수단은 1:n 관계다 등의 관계에 대해서 도식화 하고,

각 클래스 다이아그램을 표현해서 하위에 어떤 메소드가 있는지,

상속 구조는 어떻게 되는지 등을 명시하는 것이다.

건축으로 이해하는 소프트웨어 아키텍처 | 설계와 아키텍처의 차이점 - 한빛+

아키텍처 관점

반면 아키텍처는 클래스 라는 작은 소스코드 단위를 생각하지 않는다.

주문 처리 시스템을 아키텍처 관점으로 논할려면 아예 서비스가 별개로 있어야한다.

주문 배치 서비스가 있고, 결제 대행 서비스와 연결되며,

결제 대행 서비스는 신용카드 서비스와 선물카드 서비스와 연결되어 있다.

각각의 서비스는 자체적인 DB를 가지고 있다 수준까지 나와야 하는 것이다.

여기서 설계는? 각 서비스 별로 내부 클래스 파일을 정의할 것이다.

클래스와 서비스의 체급 차이 정도인 것이다.

아키텍처와 설계 사이

두 개념 사이에 체급 차이는 존재하지만,

현실세계가 복잡하듯이 문제에 대한 정의도 이건 아키텍처야 이건 설계야로 나뉘지는 않는다.

아키텍처와 설계라는 스펙트럼 사이에 어딘가에서 비중에 따라 위치하게 되는 것이다.

건축으로 이해하는 소프트웨어 아키텍처 | 설계와 아키텍처의 차이점 - 한빛+

이 비중을 나누는데에는 크게 3가지 요소가 개입한다.

  1. 전략적인가 전술적인가: 장기적이고 전반적 영향인가? 단기적이고 독립적인가?

  2. 얼만큼의 노력이 드는가: 레거시 프로젝트를 마이크로 서비스로 마이그레이션? 응 죽을게

  3. 중대한 트레이드 오프가 있나: 모두가 한달동안 야근하면 시스템이 10% 빨라져요!

전략적 vs 전술적

영향도에 따라서 뭔가 좀 복잡하고 오래걸린다? 그럼 아키텍쳐다.

여기서는 전략적인 결정이 좀 더 아키텍처와 가깝다고 할 수 있다.

전략과 전술은 어떻게 판단하는가?

  1. 결정하는데 시간과 공수 많이 필요함? => 몇일 걸리면 전략적

  2. 얼마나 많은 사람이 결정에 참여하냐 => 참여하는 사람 많을수록 건들 부분이 많다.

  3. 결정을 위해 장기적인 비전이 필요한가? => 장기적으로 붙들고 가야하면 그건 전략이 맞다.

전략과 전술 그 중간에 위치한 어중간한것을 따져보자면

적당한 시간과 소수의 참여가 필요한 일 정도가 아닐까

예를 들어 사용자 인터페이스 재설계는 나 혼자 간단히 진행할 사항은 아니지만,

프론트 개발자와 연관 되어 같이 움직여야할 수 있기 때문에 중간에 위치한다고 생각한다.

높은 수준 vs 낮은 수준의 노력

공수 생각하면 된다.

갑자기 마이크로 서비스 아키텍처 도입한다고 시스템 다 뿌셔뿌셔 클래스 다 쪼개쪼개 모듈 분리해 해버리면 그건 아키텍처의 영역이다.

근데 유저 화면에서 버튼 하나 위치 위에서 아래로 바꿔주세요.

이건 그냥 설계쪽에 극단적으로 가깝다.

복잡한 구조적 변경은 많은 공수가 들고

간단한 화면 변경은 낮은 노력이 필요하다.

중간을 따져 본다면 하나의 서비스를 별도의 서비스들로 분리하는 단계가 있을 수 있다.

중대한 vs 덜 중대한 트레이드 오프

마이크로 서비스를 적용한다면 다양한 특성에 대응성이 올라간다.

그럼 왜 안하냐, 복잡하고 비싸니깐

확장성, 민첩성, 탄력성, 결함 허용성 ++

VS

비용, 복잡성, 성능, 워크플로우 --

VS 영역에 놓이는 기준들과 수준이 높을수록 아키텍처 단위에서 고려해야한다.

내 클래스 파일 하나 쪼개서 여러개로 만드는 건?

유지보수성 VS 파일 개수

그닥 중대하지는 않고 설계에 가깝다.

3가지 개념을 복합적으로 고려하자면

만약 주문 배치 서비스와 재고 관리 서비스 간의 응답성 향상을 위해,

빠른 큐를 도입한다는 결정을 내려보자.

아키텍처와 설계와의 구분이 어려운 이유가 여기에 있다.

단순히 메시징 방식을 하나 바꾼다 생각했는데, 갑자기 트레이드 오프에서 리스크가 터져버리는 것이다.

이러한 현실세계의 복잡성을 판단하고 결정 내리는 것은, AI가 하기 어려운 부분이라고 판단한다.

현실세계에서 인간의 업은 결정을 내리고 책임을 지는 것이기에

우리도 장기적인 성장을 위해서 아키텍처에 대해서 공부해보자

← Previous
AI 시대 아키텍츠에게 요구되는 역할 변화와 필요한 역량
Next →
웹 요청은 어떻게 처리 되는가(인프라)