Skip to content

Latest commit

 

History

History
113 lines (78 loc) · 10.5 KB

File metadata and controls

113 lines (78 loc) · 10.5 KB

아키텍처 사고

아키텍처적인 관점에서 사물을 바라보는 것아키텍처 사고라고 한다.
이번에는 이러한 사고 방식을 크게 네 가지로 나눠서 살펴볼 것이다.

아키텍처 vs 설계

전통적인 역할 모델에서는 아키텍트가 아키텍처 특성을 도출하고 아키텍처 패턴과 스타일을 선택하여 컴포넌트를 구성하는 등 artifect를 만들었다.
개발팀은 이를 단방향으로 전달 받아서 컴포넌트 기반의 클래스 다이어그램을 그리고 개발을 진행했다.
하지만 이러한 단방향 관계에서는 개발팀이 아키텍퍼 결정을 임의로 결정하였더라도 이것이 아키텍트에게 전달되지 못한다.
현대의 시스템 이키텍처는 프로젝트의 단계마다, 매 이터레이션 마다 변화하고 발전하기 때문에, 아키텍트와 개발자는 장벽 없이 양방향으로 소통하고 서로 동기화될 수 있어야 한다.

기술 폭

개발자는 업무를 위해 기술의 깊이를 키워서, 전문적으로 사용할 수 있는 기술을 키우는데 주력해야 한다.
이는 지식 피라미드에서 '내가 아는 것'을 확장하는 것에 해당한다.
이와 달리 아키텍트는 기술의 폭을 넓혀서, 문제를 해결할 수 있는 솔루션을 알고 있는게 더 중요하다.
이 때 기술을 전문적으로 다루는 수준이 아니라 인식 가능한 수준의 이해가 필요하며, 이는 '내가 모른다는 것을 아는 것'의 범위를 넓히는 것을 의미한다.
물론 전문 지식도 넓으면 좋기야 하겠지만, 소프트웨어 세계는 매우 빠른 속도로 변화하기 때문에 넓은 전문 지식을 깊이 있게 유지하는 것이 어렵다.
따라서 아키텍트는 기술의 깊이 대신 기술의 폭을 넓힐 수 있는 방향으로 노력해야 한다.

트레이드오프 분석

아키텍처는 모든 것이 트레이드 오프이기 때문에, 각 솔루션의 트레이드오프를 분석하여 현재의 비즈니스 동인 및 환경 등 상황에 맞는 솔루션을 선택 할 수 있어야 한다.
대표적으로 메시징 아키텍처에는 토픽을 사용한 메시지 발행/구독 방식과, 큐를 이용한 점대점 메시징 방식이 존재하는데, 둘 중 절대적으로 더 나은 방식이란 존재하지 않는다.
토픽 메시징은 클라이언트와 적은 커플링을 가지고 아키텍처 신장성이 좋다는 장점이 있고, 점대점 큐 메시징은 보안성과 채널 별 관리 및 모니터링이 용이하다는 장점이 있다.
두 메시징 아키텍처의 특성을 고려해서, 비즈니스 및 기술 상황에 맞게 선택해야 한다.

비즈니스 동인의 이해

아키텍트는 비즈니스 동인을 이해하고, 이를 확장성, 성능, 가용성 등과 같은 아키텍처 특성으로 해석할 수 있어야 한다.
따라서 비즈니스 도메인 지식이 필요하며, 비즈니스 핵심 인사들과 원활한 협력 관계를 유지할 수 있어야 한다.

아키텍처와 코딩 실무 간 균형 맞추기

소프트웨어 아키텍트는 코딩 실무와 아키텍처 업무의 균형을 맞춰야 한다.
아키텍트는 어느 정도의 기술 깊이를 유지해야 하지만, 풀타임 개발자가 아니므로 병목 트랩에 빠지지 않도록 주의해야 한다.
(병목 트랩은 아키텍트가 프로젝트의 크리티컬 패스에 있는 코드를 책임질 때 발생)

아키텍트는 코딩을 하더라도 크리티컬 패스와 프레임워크 코드는 다른 개발자에게 넘기고, 비즈니스 기능 에 관련된 코드에 집중하는 것이 좋습니다.
이를 통해 아키텍트는 병목점이 되지 않으면서도 실무 경험을 쌓을 수 있으며, 개발자들이 겪는 문제를 직접 체험할 수 있습니다.

아키텍트가 개발팀과 함께 코딩을 하지 못하더라도 기술 깊이를 유지하고 코딩 실무 능력을 유지하기 위해서 다음의 노력들을 할 수 있다.

  1. 개념 증명(POC): 아키텍트는 POC를 통해 소스코드를 직접 작성해 아키텍처 결정을 검증할 수 있다. 예를 들어, 두 솔루션을 비교할 때 예제 코드를 작성하여 성능과 확장성 등을 비교할 수 있다. 가능하면 POC 코드는 프로덕션 수준의 고품질로 작성해서 다른 개발자들에게 좋은 샘플로 쓰일 수 있게 하면 좋다.

  2. 기술 부채나 아키텍처 스토리에 전념: 아키텍트는 개발팀이 중요한 유저 스토리에 집중할 수 있도록 기술 부채나 아키텍처 개선 작업을 맡을 수 있다. 자잘한 버그를 수정 작업을 맡는 것도 좋다. 이런 작업들은 보통 우선순위가 낮아 부담 없이 코딩 실무 능력을 유지할 수 있다.

  3. 자동화 도구 개발: 커맨드라인 도구나 분석기를 만들어 개발팀의 반복 작업을 자동화하는 것도 좋다. 예를 들어, 자동 소스 검증기를 사용해 특정 코딩 표준의 준수 여부를 검사할 수 있다.

  4. 피트니스 함수 사용: 아키텍처 컴플라이언스를 자동화하기 위해 피트니스 함수를 작성할 수도 있다. 이를 통해 실무 경험을 쌓고 아키텍처 규칙을 보장할 수 있습니다.

  5. 코드 리뷰: 코드 리뷰를 통해 아키텍처 규칙 준수 여부를 확인하고, 경험이 적은 팀원들을 멘토링할 수도 있다.

토픽 메시징 vs 큐 점대점 메시징

토픽 메시징 에서는 프로듀서가 하나의 토픽에 메시지를 발행하면, 해당 토픽을 구독하고 있는 컨슈머들이 해당 메시지를 받아서 처리한다.
이와 달리 큐 메시징 에서는 각 컨슈머 별로 별개의 큐를 운용해서, 해당 컨슈머에 전달할 메시지만 해당 큐에 발행해서 처리한다.

이 때 토픽 메시징에서는 프로듀서가 토픽 하나에만 연결하면 되므로, 메시지를 사용하는 새로운 서비스가 추가되더라도 기존 시스템은 변경하지 않아도 된다.
따라서 토픽 메시징은 아키텍처 신장성에서 강점을 가진다. 또한 프로듀서는 어떤 컨슈머가 메시지를 사용하는지 모르기 때문에 커플링이 덜 된 형태로 메시징이 설계된다.
이와 달리 큐 메시징은 보안성에서 강점을 가지는데, 큐에 전달된 데이터는 큐를 수신하는 지정된 컨슈머만 엑세스가 가능하기 때문이다.
또한 큐 메시징에서는 각 컨슈머가 별도의 계약(contract)를 맺기 때문에 자신에게 필요한 메시지만 수신할 수 있다.
추가적으로 모니터링이나 확장성 측면에서도, 각 큐마다 개별적으로 모니터링 및 로드 밸런싱이 가능하고, auto scaling을 적용하는 것도 가능하다.
이는 프로그래밍 방식의 로드밸런싱 및 모니터링이 가능함을 의미한다.

프로그래밍 방식의 로드밸런싱

프로그래밍 방식의 로드밸런싱은 소프트웨어에서 직접적으로 로드밸런싱을 제어하는 방식이다.
하드웨어 기반 로드밸런싱과 달리, 애플리케이션 레벨에서 다양한 알고리즘을 사용해 트래픽을 여러 서버나 서비스로 분배하게 된다.

주요 알고리즘으로는 다음과 같은 것들이 있다:

  1. 라운드 로빈(Round Robin): 요청을 순차적으로 각 서버에 분배하는 방식.
  2. 가중 라운드 로빈(Weighted Round Robin): 각 서버의 처리 능력에 비례해 요청을 분배하는 방식.
  3. Least Connections: 가장 적은 연결을 유지하고 있는 서버에 요청을 보내는 방식.
  4. IP 해싱(Hashing): 요청자의 IP 주소를 기반으로 고정된 서버에 요청을 분배하는 방식.

소프트웨어 로드밸런싱 방식은 유연성이 높아, 트래픽 분산 방식에 대한 세밀한 제어가 가능하고, 서버나 네트워크 상태에 따라 실시간으로 동작을 조정할 수 있다는 장점이 있다.

메시징 아키텍처에서의 로드밸런싱

토픽 메시징 방식에서는 메시지 브로커가 대부분의 로드밸런싱을 처리한다.
메시지를 여러 소비자가 처리하기 때문에, 로드밸런싱을 직접적으로 제어하기 어렵다.

큐에서는 메시지 Producer가 메시지를 큐에 넣고, 소Consumer가 큐에서 메시지를 가져와 처리하는 구조로, 다음과 같이 로드밸런싱을 구성할 수 있다

  • 가중치 기반 로드밸런싱: 특정 소비자가 더 많은 메시지를 처리할 수 있도록 조정한다. 예를 들어, 소비자의 처리 능력에 따라 메시지를 가져오는 빈도를 다르게 설정하거나, 큐의 우선순위를 설정할 수 있다.
  • 동적 소비자 관리: 소비자가 동적으로 증가하거나 감소할 수 있도록 설정하여, 트래픽이 많을 때는 소비자를 더 많이 추가하고, 트래픽이 적을 때는 소비자를 줄이는 방식으로 로드밸런싱
  • 메시지 그룹핑 및 분배: 메시지를 특정 속성에 따라 그룹화하여, 특정 그룹의 메시지를 특정 소비자가 처리하도록 분배한다. 예를 들어, 특정 키 값에 따라 메시지를 분류하고, 해당 메시지만 특정 소비자가 처리하게 하여 로드밸런싱할 수 있다.
  • 큐 우선순위: 여러 큐를 두고 각 큐에 우선순위를 부여해, 중요도가 높은 메시지를 우선 처리하거나 특정 소비자가 특정 큐만을 처리하게 설정할 수 있다.

자바의 ArchUnit:

자바 프로젝트에서 아키텍처 규칙을 준수하는지 확인하는데 사용하는 라이브러리이다.
JUnit과 통합되어 있어서 테스트 코드로 아키텍처 규칙을 검증 할 수 있고, 특정 패키지는 다른 패키지에 의존해선 안 된다거나, 특정 클래스는 특정 어노테이션을 가져야 한다는 등 다양한 규칙을 검증할 수 있다.
다음 코드는 서비스 패키지의 클래스가 컨트롤러 패키지의 클래스에 의존하지 않아야 한다는 규칙을 검증한다.

public class ArchitectureTest {

    @Test
    public void 서비스_패키지는_컨트롤러_패키지에_의존하지_않아야_한다() {
        JavaClasses importedClasses = new ClassFileImporter().importPackages("com.example.myapp");

        ArchRule rule = classes()
            .that().resideInAPackage("..service..")
            .should().notDependOnClassesThat().resideInAPackage("..controller..");

        rule.check(importedClasses);
    }
}