Print
카테고리: [ Cloud Computing & MSA ]
조회수: 1734

개요

웹앱 또는 SaaS 앱을 체계적으로 만들기 위한 이상적인 방법론이다. 본 방법론에 따라서 구현된 앱은 twelve-factor app이라 하며, 다음과 같은 장점을 가질 것이다.


상세 개념

I. 코드베이스

버전 관리되는 하나의 코드베이스와 다양한 배포

 

II. 종속성

명시적으로 선언되고 분리된 종속성

종속성이란 앱 개발과 실행에 필요한 라이브러리들에 대한 앱의 의존성을 의미한다. 모든 종속성은 (1)명시적으로 선언(manifest)되고 (2)실행 환경과 분리되어야 한다. 본 특징을 만족하기 위해서 각 프로그래밍 언어는 라이브러리 배포를 위한 패키징 시스템을 함께 제공한다. (ex. Perl-CPAN, Ruby-Rubygems)

장점은 다음과 같다.

 

III. 설정

환경(environment)에 저장된 설정

여기서 설정이란, 배포의 종류마다 달라질 수 있는 환경 관련 항목을 대상으로 한다. (ex. 데이터베이스와의 연결 정보, Amazon S3 등의 외부 서비스 인증 정보, 호스트 이름)

위와 같은 환경 관련 설정은 코드와 분리되어야 한다. 대표적인 위반 사례는 코드에 상수로 위 설정을 저장하는 것이다.

 

IV. 백엔드 서비스

백엔드 서비스를 연결된 리소스로 취급

백엔드 서비스란, 애플리케이션 정상 동작 중 네트워크를 통해 이용하는 모든 서비스를 통칭한다. 

기존에는 로컬에 서비스를 포함시키던 경향과 비교할 때, 최근에는 서드파티에 의해서 제공되는 서비스를 이용하는 경우도 많다. 

Twelve-factor app은 로컬 서비스와 서드파티 서비스를 모두 구분 없이 애플리케이션과 연결된 동등한 리소스로 취급한다.

장점은 다음과 같다.

 

V. 빌드, 릴리즈, 실행

철저하게 분리된 빌드와 실행 단계

코드베이스는 3 단계를 거쳐 배포된다.

  1. 빌드 단계는 저장소의 코드로부터 종속성을 결합하여 실행 가능한 번들로 변환시킨다. 
  2. 릴리즈 단계에서는 빌드 단계에서 만들어진 빌드와 배포의 환경 설정을 결합한다. 완성된 릴리즈는 빌드와 설정을 모두 포함하며 실행 환경에서 바로 실행될 수 있도록 준비된다.
  3. 실행 단계(런타임이라고도 하는)에서는 선택된 릴리즈에 대한 애플리케이션 프로세스의 집합을 시작하고 애플리케이션을 실행 환경에서 돌아가도록 한다. 코드 베이스는 빌드가 되고, 빌드는 설정과 조합되어 릴리즈가 된다.

Twelve-Factor App은 빌드, 릴리즈, 실행 단계를 엄격하게 서로 분리한다. 예를 들어, 실행 단계에서 코드 또는 종속성을 변경할 수 없다.

특징은 다음과 같다.

 

VI. 프로세스

애플리케이션을 하나 혹은 여러개의 무상태(stateless) 프로세스로 실행

실행 환경에서 앱은 하나 이상의 프로세스로 실행된다.

Twelve-Factor앱의 실행 프로세스는 stateless로써, 앱의 운영 상 유지되어야 할 모든 데이터는 프로세스 내 메모리가 아닌 데이터베이스와 같은 안정된 백엔드 서비스에 저장되어야 한다.

따라서 각 인스턴스는 메모리 파일 등을 공유할 필요가 없도록 설계해야 하며, 인스턴스가 재실행 될 때 local file, session과 같은 상태 정보는 모두 초기화되어야 한다.

 

VII. 포트 바인딩

포트 바인딩을 사용해서 서비스를 공개함

Twelve-Factor 웹 앱은 포트를 바인딩하여 HTTP 등의 각종 프로토콜을 통해 요청을 받고 서비스를 제공한다.

예시를 보자.

특징은 하나의 앱이 다른 앱을 위한 백엔드 서비스가 될 수 있다.

 

VIII. 동시성(Concurrency)

프로세스 모델을 통한 확장

모든 컴퓨터 프로그램은 실행되면 하나 이상의 프로세스로 표현됩니다. 웹 애플리케이션은 다양한 프로세스 실행 형태를 취해왔다. 예를 들어, PHP 프로세스는 Apache의 자식 프로세스로 실행되며, request의 양에 따라 필요한 만큼 시작된다. 자바 프로세스들은 반대 방향에서의 접근법을 취한다. JVM은 시작될 때 큰 시스템 리소스(CPU와 메모리) 블록을 예약하는 하나의 거대한 부모 프로세스를 제공하고, 내부 쓰레드를 통해 동시성(concurrency)을 관리한다. 두 경우 모두 실행되는 프로세스는 애플리케이션 개발자에게 최소한으로 노출된다.

Scale는 실행되는 프로세스의 갯수로 표현되고, Workload Diversity는 프로세스의 타입으로 표현된다.

프로세스의 타입과 각 타입별 프로세스의 갯수의 배치를 프로세스 포메이션이라고 한다. 런타임 VM 내부의 쓰레드나 EventMachine, Twisted 또는 Node.js의 async/evented 모델처럼 개별 프로세스가 내부적으로 동시에 처리하는 시스템은 개별 VM이 커지는 수직 확장적인 특징이 있다. 이에 비해서 위 모델과 같이 역할에 따라서 적당한 크기의 독립적인 프로세스가, 필요에 의해서 유연하게 확장되도록 설계된 모델은 수평적으로 확장 가능하다. 

장점은 개발자는 애플리케이션의 작업을 적절한 프로세스 타입에 할당함으로서 다양한 작업 부하를 처리할 수 있도록 설계할 수 있다. 예를 들어 HTTP 요청은 웹 프로세스가 처리하며, 시간이 오래 걸리는 백그라운드 작업은 worker 프로세스가 처리하도록 한다.

특징은 다음과 같다.

 

IX. 폐기 가능(Disposability)

빠른 시작과 그레이스풀 셧다운(graceful shutdown)을 통한 안정성 극대화

프로세스는 프로세스 매니저로부터 SIGTERM 신호를 받았을 때 그레이스풀 셧다운(graceful shutdown)을 한다. 웹프로세스의 그레이스풀 셧다운 과정에서는 서비스 포트의 수신을 중지하고(그럼으로써 새로운 요청을 거절함), 현재 처리 중인 요청이 끝나길 기다린 뒤에 프로세스가 종료된다. 

특징은 다음과 같다.

방법은 어떨까?

 

X. dev/prod 일치

development, staging, production 환경을 최대한 비슷하게 유지

development, staging, production 환경을 최대한 비슷하게 유지한다.

Twelve-factor 앱은 개발 환경과 production 환경의 차이를 작게 유지하여 지속적인 배포가 가능하도록 디자인되어야 한다.

배경은 이렇다.

서비스 간의 불일치가 개발 환경과 스테이징 환경에서는 동작하고 테스트에 통과된 코드가 production 환경에서의 오류를 일으킬 수 있다. 이는 지속적인 배포를 방해하며, 앱의 라이프사이클을 고려할 때 지속적인 배포의 둔화가 발생시키는 손해는 매우 크다. 특히, 데이터베이스, 큐잉 시스템, 캐시와 같은 백엔드 서비스는 dev/prod 일치가 중요한 영역 중 하나이다.

특징은 다음과 같다.

 

XI. 로그

로그를 이벤트 스트림으로 취급

로그는 모든 실행중인 프로세스와 백그라운드 서비스의 아웃풋 스트림으로부터 수집된 이벤트가 시간 순서로 정렬된 스트림이다. 각 프로세스는 이벤트 스트림을 버퍼링 없이 stdout에 출력하고 Twelve-Factor App은 로그 파일을 작성하거나, 관리하지 않는다.

방법은 이렇다.

  1. 스테이징이나 production 배포에서는 각 프로세스의 스트림은 실행 환경에 의해서 수집된다.
  2. 그 다음, 앱의 다른 모든 스트림과 병합되어 열람하거나 보관하기 위한 저장소로 전달된다.
  3. 목적지들은 앱이 열람하거나 설정할 수 없고, 실행 환경에 의해서 완벽하게 관리된다. (예: Logplex, Fluentd 활용)

특징이라고 하면, 이러한 시스템은 장기간에 걸쳐 앱의 동작을 조사할 수 있는 강력함과 유연성을 가지게 된다.

조사 예시는 다음과 같다.

 

XII. Admin 프로세스

admin/maintenance 작업을 일회성 프로세스로 실행

앱의 일반적인 기능들(예: Web request의 처리)을 처리하기 위한 프로세스들의 집합과는 별도로 개발자들은 종종 일회성 관리나 유지 보수 작업을 필요로 하는데, 이러한 작업은 스크립트 등의 일회성 프로세스로 실행되어야한다.

예시를 보자.

특징은 다음과 같다.

 

 

Reference.