MSA

👨‍👧‍👦 AntiFragile 과 Cloud Native(feat. 12Factors)

늦은산책 2024. 3. 25. 13:32

시스템의 구성이 이전과 다르게 Local 에서 Cloud로 개선되었고 그로 인해 확장성과 안정성이 강화되었고 지속적인 변동이 발생하더라도 시스템을 유연하게 사용할 수 있도록 개선되었다. 

 

이러한 시스템을 구성하는 대표적인 특성을 AntiFragile 과 Cloud Native 의 방식을 가지고 정리할 수 있다.

 

⚡ AntiFragile

이전까지의 시스템은 Fragile 즉, 깨지기 쉬운 성격을 가지고 있었다. 하지만 최근에는 이와 상반되는 AntiFragile의 성격을 가지고 개발이 된다는 것을 알수가 있다.

 

Auto Scaling ( 자동 확장성 )

  • 시스템을 구성하는 인스턴스를 auto scaling group으로 묶어 유지되어야 하는 최소 인스턴스를 지정하고, 사용량에 따라 변동이 가능한 방식을 사용하는 것이다.

Microservices

  • Cloud Native Application의 핵심이다.
  • 개별적인 모듈이나 기능을 독립적으로 개발하고 배포, 운영을 할 수 있는 서비스이다.

Chaos Engineering

  • 프로덕션 서비스의 각종 장애 조건을 견딜 수 있는 시스템의 신뢰성을 확보하기 위해 분산 시스템을 배우는 것이다.
  • 시스템의 급격하고 예측 불가능한 상황에도 안정적인 서비스를 구축해야한다.

Continuous Deployments

  • 수십, 수백개의 MSA를 배포하는 과정에 빠른 적용이 가능하다.
  • 큰 예로 CI, CD가 있다.

 

⚡ Cloud Native

Cloud Native Architecture

1. 확장 가능한 아키텍처

  • 수평적인 확장이 가능하다. 때문에 더 많은 사용자의 요청을 처리하기 편하다
  • 확장된 시스템의 부하 분산으로 가용성을 보장한다. 시스템을 확장하는 방식에는 2개가 있다 
    • Scale - Up : 하드웨어적 사양을 높인다.
    • Scale - Out : 같은 사양의 인스턴스를 여러 대 배치해서 동시에 많은 사용자를 요청을 처리한다.
  • 시스템 또는 서비스 어플리케이션 단위의 패키지인 컨테이너 기반 패키지가 있다.
  • 현재 사용되고 있는 시스템의 상황과 리소스의 사용 현황을 파악 할 수 있도록 모니터링이 될 수 있다.

2. 탄력적 아키텍처

  • 서비스 생성에서 배포까지의 시간을 크게 단축시킨다.
  • 분할 된 서비스 구조를 가지고 있다
  • 도메인 특성에 따라 서비스 경계를 구분하고 개발해야 한다.
  • 서로 분리된 서비스 간의 원활한 통신을 위해, 서비스간의 종속성을 최소화 시키게 되고 상태를 갖지 않도록 해야한다.
  • 서비스의 추가와 삭제하여 연결된 서비스에서 해당 서비스를 사용할 수 있다. ( 각 서비스는 discovery service에 등록되고 삭제 된다.)

3. 장애 격리

  • 하나의 서비스에서 발생하는 문제가 전체 서비스에 영향이 가지 않는다.

 

Cloud Native Application

Cloud Native Architecture에 의해 설계되고 구현된 서비스를 부르는 명칭이다. 이는 앞서 말한 Cloud Native Architecture와 AntiFragile의 특성을 가지고 구성을 한다.

 

1. Microservice로 개발된다.
2. 개발이 완료된 서비스는 CI/CD 를 통해 자동으로 통합, 빌드, 테스트가 진행된다
3. 문제가 발생한다면 DevOps를 통해 수정해서 배포를 할 수 있다. 
4. 완성된 어플리케이션을 Container를 사용해서 관리한다.

 

CI/CD

  • 지속적인 통합
    • 통합 서버, 소스관리, 빌드 도구, 테스트 도구
    • 대표적으로 Jenkins, Team CI, Travis CI가 있다. 이러한 시스템을 형상관리 시스템과 연동하여 사용하게 된다.
  • 지속적 배포
    • Continuous Delivery ( 지속적인 전달 )
      • 수정되야 하는 문제가 발생하면 중간 관리자가 수정하여 반영해서 실행한다
    • Continuous Deployment ( 지속적인 배포 )
      • 관리자의 개입 없이 실행 환경까지의 배포가 자동적으로 이루어진다.
    • 카나리 배포, 블루 그린 배포
      • 카나리 배포 : 전체 사용자의 95% 는 이전 버전을 사용하고 5% 만이 새로운 버전을 사용한다
      • 블루 그린 배포 : 100% 의 사용자가 모두 새로운 버전을 사용하게 된다.

 

DevOps

  • 개발 조직과 운영 조직의 통합으로 인해 요구사항이 발생하면 빠르게 반영 할 수 있다.

 

Container 가상화

기존의 Local 환경에서 저장하고 유지해야 하지만 Cloud로 이전하여 적은 비용을 통해 탄력성 있는 시스템을 구축할 수 있게 되었다.

1. Traditional Deployment

  • 전통적인 방식으로 한 개의 운영체제 위에 다양한 어플리케이션을 운영한다.

2. Virtualized Deployment

  • Hypervisor를 통해 가상머신을 등록하고 기존 시스템의 물리적인 하드웨어를 나누어 사용한다. 때문에 하나의 가상머신은 독립적으로 운영이 가능하다.

3. Container Deployment

  • Container 기술을 위한 소프트웨어를 작동해서 각각의 필요한 리소스나 라이브러리를 독립적으로 사용하게 되면서 기존의 하드웨어보다 더 적은 리소스를 사용하게 되면서 가볍고 빠른 운영이 가능하다.

 

⚡ 12Fators

SaaS 어플리케이션을 만들기 위한 방법론으로 언어에 비종속적이고 DB, Queue, Memory-Cache 등과 조합할 수 있는 방법론
시간이 지나면서 망가지는 소프트웨어 유지비용을 줄이는 이상적인 방법을 나타낸다.

1. CodeBass

  • 코드 베이스는 VCS를 사용해서 변화를 추적하고 코드를 저장하는 저장소를 의미한다 코드는 한곳에서 개발되고 배포되어야한다.

2. Dependencies

  • 전체 시스템에서 사용하고 있는 모든 종속성은 명시적으로 선언되어야 한다. Java는 Maven 이나 Gradle을 이용해서 관리한다.

3. Config

  • 설정은 동일한 앱의 배포 단계에 따라 달라질 수 있는 모든 것이다. 이러한 정보들은 코드상에 저장되어선 안되고 WAS에도 저장하지 않아야 한다.
    • 데이터베이스 접속 정보
    • OAuth 또는 외부 서비스 인증 정보
    • 호스트 네임에 따라 달라지는 값
    • 서비스 포트 정보

4. Backing Services

  • 네트워크를 통해 이용하는 모든 서비스, 서드파티 서비스 또한 포함된다.
    • 데이터 베이스, 메시지 큐, SMTP, 캐시, Push, S3, map 등등
  • 각각의 연결된 리소스로 취급하고 자유롭게 연결 및 분리가 가능해야하고 코드 수정 없이 전환이 가능해야 한다
  • 이러한 연결 정보를 Config로 지정해 주어야한다.

5. Build, Release, Run

  • 코드는 빌드, 릴리즈, 실행 단계로 엄격하게 분리한다. 코드 변경은 빌드 단계이여야만 하고 모든 릴리즈는 항상 유니크한 릴리즈 아이디를 가져야한다. 또 릴리즈는 추가만 가능하고 변경이 불가능 하다. 
  • 빌드
    • 코드 베이스를 빌드라는 실행 가능한 번들로 변환
    • 새로운 코드가 배포 될 떄마다 개발자에 의해 시작
  • 릴리즈
    • 빌드 단계에서 만들어진 빌드와 배포의 현재 설정을 결합하는 단계
  • 실행(런타임)
    • 서버가 재부팅되거나 프로세스 매니저에 의해 실행된것

6. Process

  • 모든 어플리케이션은 Stateless 상태로 실행되어야 한다. 이는 서로의 정보가 공유되지 않아야한다는 뜻이다. 유지가 될 필요가 있는 모든 데이터는 데이터 베이스, Redis에 저장되어야한다.

7. Port Binding

  • 서로의 서비스에서 런타임이 아닌 HTTP 서비스로 접근할 수 있도록 포트 바인딩이 되어야 한다.
    • A가 B를 사용해야하는 경우 B의 데이터베이스 접속 정보와 계정, 권한을 A에게 부여해 B의 데이터베이스에 접속하지 않아야 한다.

8. Concurrency

  • 어플리케이션은 Scale-Out이 가능해야하며, 프로세스가 데몬 형태가 아니여야 한다. 이는 앞선 Stateless 속성으로 인해 자유로운 확장과 축소가 가능했다.

9. Disposability

  • 서비스의 시작 시간과 종료시간의 단축은 필수가 된다. 또한 종료에 있어 종료 시그널을 받고 나서 어플리케이션은 신규요청은 받지 않고 기존 요청은 최대한 빠르게 처리한 이후 종료되어야한다. (graceful shutdown)

10. Development / Production Parity

  • 개발 환경, 스테이징 환경, 프로덕션 환경을최대한 비슷하게 유지해야하는 것 보통 이 3단계 사이에는 세 가지의 큰 차이점이 있다
    • 시간의 차이
      • 개발자가 작업한 코드는 프로덕션에 반영되기까지 시간이 소요된다
    • 담당자의 차이
      • 대부분의 경우 개발자가 작성한 코드를 시스템 엔지니어가 배포한다.
    • 툴의 차이
      • 배포 환경과 개발자의 환경이 OS부터 사용 제품, 툴에 있어 다를 수 있다.

11. Logs

  • 모든 실행중인 프로세스와 서비스의 아웃풋 스트림으로부터 수집된 이벤트가 시간순으로 정렬된 스트림이다. 때문에 어플리케이션은 아웃풋 스트림의 전달이나 저장에 절대 관여하지 않는다.

12. Admin Process

  • admin 또는 유지보수 작업을 일회성 프로세스로 실행해야 한다.

12 + 1. API first

  • API로 통신하는 서비스이기 때문에 사용자가 어떤 API를 통해 데이터를 가져올 것인가를 먼저 고민해야한다.

12 + 2. Telemetry

  • 모든 지표는 시각화, 수치화 되어 관리할 수 있어야 한다.

12 + 3. Authentication, Authorization

  • API를 사용할 때 인증과 인가는 필수로 적용되어야 한다.