[DEV] 기록

The Twelve Factors App (12 팩터 앱)

꾸준함. 2023. 2. 25. 06:47

개요

12 팩터 앱 방법론은 Heroku에서 제시한 모범 사례 지침이며 클라우드 네이티브 마이크로 서비스를 구축할 때 동적인 확장과 기본 사항에 관한 개발 및 설계 지침의 모음입니다.

해당 방법론은 클라우드 네이티브 앱을 구축하면서 흔히 발생할 수 있는 문제에 대해 용어를 제공할 뿐만 아니라 이러한 문제들에 대한 해결책도 제공합니다.

곧 Spring Cloud MSA가 적용된 프로젝트를 진행할 예정이기 때문에 12 팩터 앱 방법론을 간략하게 정리해 보겠습니다.

 

https://www.linkedin.com/pulse/thetwelve-factor-app-methodology-ashish-kumar-singal/

 

클라우드 네이티브 애플리케이션

12 팩터 앱에 대해 정리하기 전에 우선 클라우드 네이트브 앱에 대한 개념 정리가 필요합니다.

클라우드 네이티브 애플리케이션은 클라우드 컴퓨팅 아키텍처의 장점과 서비스를 활용할 수 있도록 특별히 설계된 앱입니다.

기존 시스템에서의 애플리케이션은 클라우드의 이점을 100% 활용하지 못했다면, 마이크로서비스 아키텍처를 채택하여 컨테이너, 쿠버네티스와 같은 기술과 도구, DevOps, Agile 방법론 등을 도입하여 개발자 생산성, 비즈니스 민첩성, 확장성, 가용성 및 비용 절감 효과를 크게 높일 수 있습니다.

클라우드 네이티브 개발을 위한 네 가지 원칙은 아래와 같습니다.

  • DevOps
  • Micorservice
  • CD (Continuous Delivery)
  • Container

 

1. Devops

 

개발(Develop)과 운영(Operations)의 약어로 개발자와 IT 운영 간 커뮤니케이션과 협업, 통합에 중점을 둔 소프트웨어 개발 방법론을 의미합니다.

DevOps에서는 소프트웨어 개발과 운영을 하나의 통합적인 과정으로 보며, 이를 위해 Jenkins와 Jira 같은 툴을 사용합니다.

개발팀과 운영팀이 함께 일하면서, 개발자는 애플리케이션 개발에 집중하고, 운영자는 시스템 운영에 집중할 수 있도록 지원합니다. (이론상 그렇지만 경험상 타 팀과의 협업은 언제나 어렵습니다...)

 

2. Microservice

 

마이크로서비스는 작고, 느슨하게 결합된 분산 서비스입니다.

마이크로서비스를 이용하여 대규모 애플리케이션을 관리하기 쉬운 독립적인 컴포넌트로 분리할 수 있습니다.

또한 명확히 정의된 작은 조각으로 분해하여 대규모 코드베이스에서 발생하는 전통적인 복잡성 문제를 해결하는데 도움이 될 수 있습니다. (Monolithic과 반대되는 개념)

 

3. CD (Continous Delivery)

 

요즘 CI/CD 얘기가 많이 나오기 때문에 용어는 들어봤을 것입니다.

CD를 실천하면 소프트웨어 전달 프로세스를 자동화하여 운영 환경에서 단기간 배포가 가능합니다.

CD의 가장 큰 특징은 빠른 피드백이라고 할 수 있습니다.

개발자들은 소스 코드 변경사항을 자주 배포하며, 자동화된 테스트를 통해 변경사항에 대한 검증을 빠르게 받을 수 있으며  이를 통해 결함이 발견되면 빠르게 수정하고, 소프트웨어 품질을 높일 수 있습니다.

연속적인 배포를 위해서는 자동화된 테스트와 배포 과정이 필요하며 이를 위해 젠킨스와 같은 CI/CD 툴이 사용됩니다.

 

4. Container

 

개발자가 서비스를 한 VM 전체에 배포를 하는 대신 클라우드에 도커 컨테이너로 배포합니다.

 

12 팩터 앱

본론으로 돌아와 12 팩터 앱을 간략히 정리해 보겠습니다.

 

1. Codebase (코드베이스)

 

각 마이크로서비스는 버전 관리되는 git 혹은 svn과 같이 소스 제어 가능한 단일 코드베이스를 가집니다. 

코드베이스는 여러 배포 환경(local, dev, test, staging, prod)을 포함할 수 있지만 다른 마이크로서비스와 공유되지 않는다는 것이 특징입니다.

만약 타 마이크로서비스와 공유가 될 경우 dependency가 생겨 제약 사항이 생길 수 있기 때문입니다.

 

2. Dependencies (종속성)

 

애플리케이션이 Maven 혹은 Gradle과 같은 자바용 빌드 도구로 사용하면 항상 동일한 라이브러리 버전으로 마이크로서비스를 빌드할 수 있습니다.

Maven의 경우 pom.xml 파일에 정의된 의존성을 읽어 로컬 Maven 저장소(.m2 repository)에서 검색하고 로컬에 없는 jar 파일일 경우 중앙 Maven 저장소(Central Maven Repository)에서 내려받고 추후 사용을 위해 로컬 저장소에 추가합니다.

내부망에서 개발할 경우 nexus repository에 저장된 라이브러리만 사용하도록 제한하기도 합니다.

 

3. Config (구성 정보)

 

마이크로서비스에서 명심해야 할 부분은 절대로 소스 코드에 설정 정보를 추가하지 않는 것입니다.

설정 정보의 경우 배포할 마이크로서비스와 완전히 분리해서 관리하는 것이 최선이며 Spring Cloud의 경우 Config Server를 별도로 배치한 뒤 config 정보가 바뀔 경우 별도 배포 없이 kafka 혹은 rabbitmq를 통해 bus refresh를 하여 Eureka 서버에 등록된 서버에 적용해 줍니다.

만약 소스 코드에 설정 정보가 있을 경우 모든 마이크로서비스를 재배포해야 하기 때문에 비효율적입니다.

 

4. Backing Services(백엔드 서비스)

 

마이크로서비스는 대개 다른 서버와 네트워크로 통신합니다.

이 경우 애플리케이션의 코드 변경 없이 로컬 및 써드 파티와 연결하는데 배포 구현체를 교체할 수 있어야 합니다.

예를 들어 별도 코드 수정 없이 요구사항에 따라 파일을 NAS에 저장하다가 AWS S3에 저장할 수 있어야 합니다.

추상화가 중요!

 

5. Build, Release, Run(빌드, 릴리즈, 실행)

 

애플리케이션 배포 단계 즉, 빌드, 릴리즈, 그리고 실행 단계는 철저히 분리되어야 합니다.

코드가 빌드되면 런타임 변경 사항은 빌드 프로세스를 거쳐 재배포되어야 하고 빌드된 서비스는 변경될 수 없어야 합니다.

각 단계를 분리하지 않을 경우 변경 사항을 추적하지 못하거나 별도 공수를 들여 코드를 수정해야 하는 일이 발생할 수 있습니다.

예를 들어 prod 환경에 이미 배포된 서비스를 변경한다면, 이 변경 사항은 코드베이스에 저장되지 않아 서비스의 새 버전에 변경 사항이 누락되거나 새 버전에 변경 사항을 다시 복사해야 하는 사항이 발생할 수 있습니다.

 

6. Process(프로세스)

 

마이크로서비스는 항상 stateless 상태가 되어야 하며 요청받은 트랜잭션을 수행하는 데 필요한 정보만 포함해야 합니다.

마이크로서비스는 서비스 인스턴스 손실로 데이터가 손실될 것이라는 걱정 없이 언제든 중단 및 교체 가능해야 합니다.

상태를 저장해야 할 경우 Redis와 같은 메모리 케시나 백업 DB를 사용하여 수행할 수 있습니다.

 

7. Port Binding(포트 바인딩)

 

포트 바인딩은 애플리케이션이 특정 포트 번호를 사용하도록 지정하는 것입니다.

포트는 IP 주소와 결합하여 네트워크 통신에서 사용되며 애플리케이션이 특정 포트 번호와 결합되어 실행될 때, 해당 포트를 통해 들어오는 모든 요청은 애플리케이션으로 전달됩니다.

특정 포트 번호를 사용함으로써, 애플리케이션은 네트워크에서 요청을 받고, 응답을 전송할 수 있습니다. 

마이크로서비스 아키텍처에서 마이크로서비스는 서비스 실행 파일로 패키징 된 서비스용 런타임 엔진이 포함되어 완전히 독립적입니다.

따라서, 별도의 웹서버나 애플리케이션 서버 없이 서비스를 실행할 수 있어야 하며 해당 서비스는 노출된 HTTP 포트를 사용하여 바로 액세스가 가능해야 합니다.

 

8. Concurrency(동시성)

 

클라우드 네이티브 애플리케이션은 병렬 처리를 지원해야 합니다.

애플리케이션은 대개 동시에 처리해야 할 많은 요청이 있는데 이때 동시성을 지원하지 않으면, 애플리케이션은 하나의 요청을 처리할 때까지 다른 요청을 처리하지 못하고 기다려야 하는 문제가 발생합니다.

이는 애플리케이션의 처리 속도를 저하시키고, 사용자 경험을 저하시킬 수 있습니다.
따라서 12 Factor App에서는 애플리케이션이 병렬 처리를 지원하도록 설계해야 한다고 강조하고 있습니다.

동시성 향상을 위해서는 수직 확장 혹은 수평 확장을 적용할 수 있습니다.

수직 확장은 인스턴스의 하드웨어를 spec up 시키는 것이며 주로 ram을 늘립니다.

수평 확장의 경우 애플리케이션의 인스턴스를 더 추가하는 것입니다.

12 팩터 앱에서는 확장이 필요할 경우 수직 확장 대신 더 많은 인스턴스를 띄워서 수평 확장하는 것을 추천합니다.

 

9. Disposability(폐기 가능)

 

Disposability란 애플리케이션이 즉시 시작되고 중지될 수 있는 능력을 가지고 있어야 한다는 것을 의미합니다.

이를 통해 애플리케이션의 가용성을 높일 수 있으며, 장애 발생 시 복구 시간을 최소화할 수 있습니다.
Disposability를 구현하기 위해서는 다음과 같은 요소를 고려해야 합니다.

  • 프로세스의 빠른 시작과 중지: 애플리케이션이 시작되고 중지되는 데 걸리는 시간을 최소화해야 하며 이를 위해 프로세스의 초기화 과정을 간소화하고, 미리 초기화된 상태에서 시작할 수 있도록 해야 합니다.
  • 상태 저장 및 복원:가용성을 높이기 위해 애플리케이션이 중지되더라도 이전 상태를 저장하고 복원할 수 있어야 합니다. 
  • 무상태(Stateless) 설계: 가용성을 높이기 위해 애플리케이션은 외부 상태에 의존하지 않고, 모든 상태 정보를 로컬 스토리지나 캐시 등에 저장해야 합니다.


Disposability는 클라우드 네이티브 애플리케이션을 구현하는 데 매우 중요한 요소입니다.

클라우드 환경에서는 애플리케이션이 자주 시작되고 중지되기 때문에, Disposability를 고려하지 않으면 애플리케이션의 가용성이 저하될 수 있습니다.

 

10. Dev/Prod Parity(개발 및 운영 환경 일치)

 

애플리케이션이 dev 환경, staging, prod 환경에서 최대한 일치해야 한다는 것을 의미합니다.

이를 통해 애플리케이션의 배포 및 운영 과정에서 발생하는 문제를 최소화할 수 있습니다.
Dev/Prod Parity를 구현하기 위해서는 다음과 같은 요소를 고려해야 합니다.

  • 동일한 환경 설정: 개발 환경과 운영 환경의 환경 설정이 가능한한 일치해야 합니다. 
  • 동일한 종속성 관리: 개발 환경과 운영 환경에서 사용되는 종속성이 동일해야 합니다. 
  • 동일한 배포 프로세스: 개발 환경과 운영 환경에서의 배포 프로세스가 동일해야 합니다. 

 

11. Logging(로깅)

 

MSA 구조를 채택할 경우 서비스가 분산되어 있기 때문에 각각의 서비스에서 발생하는 로그도 분산되어 있습니다.

따라서 각 마이크로서비스에서 출력된 로그는 수집되고 중앙 저장소에 기록하는 logstash나 fluentd와 같은 도구로 관리해야 합니다.

여기서 중요한 점은 각각의 마이크로서비스는 이러한 내부 동작 메커니즘에 관여하지 않고 표준 출력으로 로그를 기록하는 것에만 집중한다는 것입니다.

경험상 주로 ELK 스택으로 로그를 전송하는 자동 구성 방식을 구축하며 간혹 EFK 스택으로 중앙 집중화 로깅 시스템을 구축한 곳도 있는 것 같습니다.

 

12. Admin Process(관리 프로세스)

 

애플리케이션 관리 작업을 위한 별도의 프로세스를 사용하는 것을 의미합니다.

이러한 프로세스는 일반적으로 백그라운드로 실행되며, 애플리케이션의 데이터베이스나 캐시 등을 관리하는 데 사용됩니다.

관리 프로세스는 다음과 같은 작업을 수행합니다.

  • 데이터베이스 마이그레이션: 데이터베이스 스키마 변경 등과 같은 데이터베이스 관리 작업을 수행합니다.
  • 백업과 복원: 데이터베이스나 파일 시스템 등을 백업하고, 복원하는 작업을 수행합니다.
  • 캐시 관리: 캐시 메모리를 관리하고, 필요에 따라 초기화하는 작업을 수행합니다.
  • 세션 관리: 세션 데이터를 관리하고, 만료된 세션을 삭제하는 작업을 수행합니다.
  • 로그 관리: 애플리케이션 로그를 관리하고, 필요한 경우 압축하거나 삭제하는 작업을 수행합니다.

 

위와 같은 프로세스는 소스 코드 저장소에서 관리 및 유지되는 스크립트로 수행되어야 하며 스크립트가 실행되는 모든 환경에서 반복 가능하고 변경되지 않아야 하며 각 환경에 따라 개별 수정되지 않아야 합니다.

 

참고

스프링 마이크로서비스 코딩 공작소 개정 2판 1장

 

Chatgpt

 

https://12factor.net/

 

The Twelve-Factor App

Background The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the Heroku pla

12factor.net

 

https://www.linkedin.com/pulse/thetwelve-factor-app-methodology-ashish-kumar-singal/

 

The Twelve-Factor App methodology 

Introduction In the modern era, software is commonly delivered as a service: called web apps, or software-as-a-service. The twelve-factor app is a methodology for building software-as-a-service apps that: •Use declarative formats for setup automation

www.linkedin.com

 

 

반응형