Sevice Decomposition Patterns

Sevice Decomposition Patterns

Decompose by business capability

Context

큰 시스템을 개발하는 경우나 복잡한 어플리케이션을 개발하고 있고, 마이크로 서비스 아키텍처를 이용하고 있다면.

마이크로 서비스 아키텍처 구조는 느슨하게 결합된 서비스들의 모임이라고 할 수 있다.

마이크로서비스 아키텍처의 목표는 지속적인 개발/배포를 통해서 소프트웨어 개발의 가속도를 향상 시키는데 있다.

성공적인 소프트웨어 개발

https://microservices.io/i/successtriangle.png

프로세스:

  • 지속적인 개발 및 배포

아키텍처:

  • 마이크로 서비스 아키텍처

조직:

  • 작은 조직
  • Agile
  • autonomous
  • cross functional teams

마이크로 서비스 아키텍처는 2가지 방법으로 수행한다.

  1. 단순화된 테스팅, 독립적으로 배포된 서비스 컴포넌트
  2. 작고, 자치적인 팀의 집합으로 엔지니어링 조직이 구성된다. 각각은 하나 혹은 여러개의 서비스를 책임진다.

이런 구조가 자동으로 이점을 주는 것은 아니다. 그러나 이는 어플리케이션의 분리를 서비스로 분리할때 신중히 결정하는 것으로 달성이 된다.

  • 서비스는 반드시 작고, 작은 팀에 의해서 개발이 이루어져야한다.
  • OOD(Object Oriented Design) 가이드라인의 유용성은 SRP(Single Responsibility Princciple) 에 있다.
  • SRP 는 클래스의 책임을 변경하는 것이 오직 하나의 이유에서 변경이 되어야함을 의미한다.
  • 그리고 상태는 오직 한가지 사유로 변경이 되어야한다.
  • SRP 를 서비스 설계와 응집력 있고, 강력하게 연관된 작은 서비스를 설계하는데 적용하는 것이 합리적이다.

  • 어플리케이션은 신규나 변경된 요구사항을 하나의 서비스에만 영향을 미치도록 분리 되어야한다.
  • 복수개의 서비스에 영향을 주는 방법으로 분리가 되면, 여러 팀에 걸쳐서 협업이 필요하게 된다. 이는 개발을 느리게 한다.
  • 다른 유용한 OOD 원칙은 Common Closure Principal(CCP) 이다. 이것은 동일한 이유로 동일한 패키지 내의 클래스에 수정이 이루어 져야한다는 것을 말한다.
  • 만약 동일한 비즈니스 룰의 관점에서 서로다른 클래스에서 구현이 아마도 필요한 경우 일 것이다.
  • 목표는 비즈니스 룰 변경은 오직 작은 수의 코드 변경만이 필요하도록 설계해야한다. 이상적으로 패키지에서 오직 하나의 클래스만 변경
  • 각 변경은 오직 하나의 서비스에만 영향을 주어야한다.

강조

  • 아키텍처는 반드시 안정 적이어야한다.
  • 서비스들은 반드시 응집도 있어야한다. 서비스는 강하게 연관된 함수의 작은 셋의 구현만 해야한다.
  • 서비스는 반드시 CCP(Common Clouse Principal) 가 이루어 지도록 보장해야한다. 오직 하나의 서비스에 변경만 일어난다는 의미이다.
  • 서비스는 반드시 느슨한 결합을 해야한다. 각 서비스 API 는 해당 구현을 캡슐화 해야한다. 구현은 클라이언트의 변경없이 수정이 되도록 해야한다.
  • 서비스는 테스트가 가능해야한다.
  • 각 서비스는 2피자 팀 단위로 충분히 작아야한다. 팀의 조직은 6 - 10명이 적당하다.
  • 각 팀은 하나 혹은 여러 서비스들를 자치적으로 운영해야한다. 팀은 반드시 자신의 서비스를 다른팀의 협조를 최소화 해서 개발 배포 되어야한다.

해결책

  • 비즈니스를 수용하기 위한 서비스를 정의헤애힌다.
  • 비즈니스 수용은 비즈니스 아키텍처 모델리으로 부터 개념화 한다.
  • 비즈니스는 가치를 창출하는 것이어야한다.
  • 비즈니스 수용성은 비즈니스 객체와 협업한다.
    • 주문 관리는 주문과 연관되어야한다.
    • 커스터머 관리는 커스터머와 연관되어야한다.
  • 비즈니스 수용성은 복수 레벨 계층 구조로 조직화 된다.
  • 예를 들어 기업 어플리케이션은 탑 레벨의 카테고리를 가지고 있으며 Product/Service 개발, Product/Service 디플로이 등을 수행한다.

이점

  • 비즈니스 기능이 비교적 안정적이므로 안정적인 아키텍처
  • 개발 팀들은 Cross-Functional 팀이며, 차지적으로 동작한다. 그리고 기술적인 기능보다 비즈니스 가치를 전달할 수 있다.
  • 서비스들은 느슨한 결합과, 강한 결합도를 가진다.

고려사항

  • 어떻게 비즈니스 수용성을 정의할 것인가?
    • 비즈니스 수용성을 정의하는 것과, 비스니스 요구사항이 필요하다.
    • 조직의 비즈니스 수용성들은 조직의 목적, 구조, 비즈니스 프로세스, 그리고 전문성의 영역이다.
  • 바운디드 컨텍스트들은 반복적인 프로세스를 이용하여 명확히 구성이 된다.
  • 좋은 비즈니스 수용성을 적용하는 것은 좋은 시작 포인트이다.
    • 조직 구조 - 조직 내의 다른 그룹들은 비즈니스 수용성이나, 비즈니스 그룹의 수용성과 대응된다.
    • 높은 수준의 도메인 모델 - 비즈니스 수용성은 도메인 객체에 대응된다.

Decompose by subdomain

  • 도메인 드리븐 디자인 방식의 서브 도메인으로 서비스를 정의한다.
  • DDD 는 어플리케이션 문제 영역을 다룬다. (비즈니스를 도메인으로 생각한다.)
  • 도메인은 복수개의 서브 도메인으로 구성이 된다.
  • 각 서브 도메인은 비즈니스의 다른 파트와 연동이 된다.

  • 서브 도메인은 다음과 같이 정의된다.
    • Core: 비즈니스를 위한 핵심 구분자, 어플리케이션에서 가장 가치 있는 부분
    • Supporting: 연관된 비즈니스 도메인, 그러나 구분짓지 않는다. 이것은 인하우스 혹은 아웃소싱으로 구성될 수 있다.
    • Generic: 비즈니스를 구분짓지 않는다. 그리고 기성 소프트웨어를 이용하여 구현한다.

장점

  • 비즈니스 기능이 비교적 안정적이므로 안정적인 아키텍처
  • 개발 팀들은 Cross-Functional 팀이며, 차지적으로 동작한다. 그리고 기술적인 기능보다 비즈니스 가치를 전달할 수 있다.
  • 서비스들은 느슨한 결합과, 강한 결합도를 가진다.

이슈

  • 서브 도메인을 어떻게 구분해야하는가?
    • 서브 도메인을 구분하는 것은 비즈니스 이해도가 필요하다.
    • 비즈니스 수용성과 같이 서브 도메인들은 비즈니스의 분석과 조직 구조, 전문 영역의 차이로 구분할 수 있다.
    • 서브 도메인들은 반복을 통해서 더 잘 구분된다.
    • 서브 도메인을 구분하는것은 좋은 시작 포인트이다.
  • 조직 구조:
    • 서브 도메인에 의해서 조직구조는 구분이 된다.
  • 구수준 도메인 모델
    • 서브 도메인은 핵심 도메인 객체를 가진다.

Service per team

  • 고성과를 내는 개발 조직은 여러개의 팀으로 구성된다.
  • 각 팀은 오래 유지되고, 작고 (5 - 9명), 느슨하게 결합되어 있고, 자치적으로 일하며, 클로스 펑서녈 팀이다.
  • 콘웨이 로의 법칙에 따라서 아키텍처는 조직의 커뮤니케이션 구조를 닮는다라고 했다.
  • 결과적으로 조직은 느슨한 팀으로 구성되고, 느슨한 아키텍처를 가진다.

  • 느슨한 아키텍처는 마이크로서비스 아키텍처와 같은 것이다.
  • 이 어플리케이션 스타일은 느슨하게 결합된 서비스들로 구성된다.
  • 하위 도메인에 따라서 분리하거나, 비즈니스 요구사항에 따라 분리하는 방법등은 서비스를 구분하도록 하고, 조직 팀은 비즈니스 구성에 따라 움직인다.
  • 그러나 서비스와 관련팀은 관련이 있는가?

  • 오너쉽을 공유하는 모델로 각 서비스에 대해서 필요에 따라 여러팀이 작업 소유권을 이용하여 작업하고 공유하는 모델이다.
  • 예를 들어 각 팀은 기능을 구현하기 위해서 여러 서비스에 걸쳐서 기능을 구현해야할 수 있다.
  • 한마디로 이 접근은 사용자 경험에 따라 팀을 배치하는 것이다.
  • 그러나 다른 한편으로는 이는 팀들 사이에 협업을 늘이게 되며, 잘못된 코드 퀄리티로 인한 리스크를 증가시키고, 코드 오너쉽을 떨어뜰이는 경우도 된다.

  • 더 낳은 접근법은 팀의 자치권을 올리고 커플링을 줄이고, 코드 오너쉽을 가져가는 것이다.
  • 팀은 비즈니스 기능을 자신의 코드 베이스를 바탕으로 책임을 진다. 이것은 하나 혹은 여러 서비스를 디플로이 하고, 결과적으로 팀은 편하게 자신의 개발을 하고, 테스트, 서비스 스케일을 자유롭게 할 수 있다.
  • 다른팀과 인터렉션은 API 협의를 통해서 수행한다.

  • 팀은 이상적으로 하나의 서비스를 소유하는 것이 좋다.
  • 팀에게 충분히 자치권을 보장하고, 느슨한 결합을 허용하고, 서비스에 복잡성과 오버헤드를 추가한다.
  • 팀이 리드타임을 극적으로 줄이는 작업이나, 혹은 확장성을 향상시키는 방향 혹은 내장애성과 같은 유형의 문제를 해결하는 경우에만 코드를 복수 서비스를 배포해야합니다.

  • 팀은 반드시 작게 유지되어야 하고, 역량의 한계를 인지하고 있어야한다.
  • 팀이 생산성을 향상 시키기 위해서 코드 베이스는 팀의 역량 범위를 넘어시지 않는 범위에서 수행해야한다.
  • 다른말로, 팀의 머리를 딱 맞추어야한다.
  • 결과적으로 서비스의 복잡도와 사이즈의 상위 경계를 잡아야한다.

핵심사항

  • 팀은 반드시 작게 유지 되어야한다. 5-9명
  • 팀은 자치적으로 운영되고, 느슨하게 결합되어야한다.
  • 팀의 크기와 복잡도에 따라 팀의 코드 베이스가 유지 되어야하며, 팀의 능력을 넘어서면 안된다.
  • 잘 정제된 서비스는 -ilities 를 향상시킨다. maintainability, testability, deployability
  • 잘 정제된 서비스는 추가적인 복잡도를 올릴 수 있다.

해결책

  • 각 서비스는 팀에 의해서 소유된다.
  • 이것은 변경에 대해서 단일 책임을 가진다.
  • 이상적인 것은 팀은 오직 하나의 서비스만을 가지는 것이다.
  • 각 팀은 하나 혹은 여러가지 비즈니스 기능을 책임진다. (비즈니스 수용성)
  • 팀은 단일 변경에 대한 책임을 가진다. 이는 코드베이스가 하나 혹은 몇개의 모듈로 구성됨을 의미한다.
  • 해당 코드 베이스는 팀의 역량을 넘어서지 않아야한다.
  • 팀의 코드 배포는 하나 혹은 몇개의 서비스로 배포 된다.
  • 팀은 반드시 하나의 서비스를 가지며, 여러 서비스가 필요한경우 이를 증명해야한다.

장점

  • 각 팀은 자치권을 가지고, 다른팀과 최소한의 영향도를 가진다.
  • 팀은 느슨하게 결합된다.
  • 팀의 자치권과 느슨한 결합을 가지면서 서비스의 최소한의 개수를 가지도록 해야한다.
  • 코드 퀄리티를 향상하도록 하며 코드의 오너쉽을 가진다.

단점

  • 팀들은 엔드유저 기능과 일치하지 않을 수 있다.
  • 서비스에 걸쳐 있는 기능을 구현하는 것은 더 많은 복잡도와 다른팀과의 협업이 필요하다.