최근 소프트웨어를 서비스 형태로 제공하게 되면서, 웹앱 혹은 SaaS(Software As A Service)라고 부르게 되었다.
Twelve-factor app 은 아래와 같은 SaaS앱을 만들기 위한 방법론이다.
- 설정 자동화를 위한 절차를 체계화 하여 새로운 개발자가 프로젝트에 참여하는데 드는 시간과 비용을 최소화 한다.
- OS에 따라 달라지는 부분을 명확히하고, 실행 환경 사이에 이식성을 극대화 한다.
- Cloud Platform 배포에 적합하고, 서버와 시스템의 관리가 필요없게 된다.
- 개발 환경과 운영 환경의 차이를 최소화 하고 민첩성을 그대화하기 위해 지속적인 배포가 가능하다.
- 툴, 아키텍쳐, 개발 방식을 크게 바꾸지 않고 scale-up 할 수 있다.
The Twelve Factors
1. 코드베이스
- 코드베이스와 app 사이에는 항상 1:1 관계가 성립되어야 한다.
- 여러개의 app 이 동일한 코드를 공유 한다면 twelve-factors 를 위반하는 것이다.
- 이를 해결하려면 공유하는 코드를 라이브러리화 시키고, 해당 라이브러리를 종속성 매니저로 관리해야 한다.
- app 의 코드베이스는 한개여야 하지만, 앱 배포는 여러개가 될 수 있다. (ex. dev, staging, prod)
2. 종속성
- 전체 시스템에 특정 패키지가 암묵적으로 존재하는 것에 절대 의존하지 않는다.
- 애플리케이션에게 시스템 도구가 필요하다면 그 도구를 애플리케이션과 통합해야 한다.
- ex) curl을 사용할 경우 curl 은 대부분의 시스템에 존재하지만 모든 시스템에 존재하는 것이 보장되는 것은 아니다. 미래의 시스템에서는 존재하지 않을 수 있고 호환되는 버전이 있으리라는 보장도 없다.
3. 설정
- 설정을 코드에서 엄격하게 분리해야 한다.
- 설정은 배치마다 크게 다르지만, 코드는 그렇지 않다.
- 애플리케이션은 종종 설정을 상수로 코드에 저장한다. 이것은 Twelve-factor를 위반한다.
- Twelve-factor app 은 설정을 환경 변수(env 라고 불림)에 저장한다. 설정 파일과 달리 잘못해서 코드 저장소에 올라갈 가능성도 낮다.
커스텀 설정 파일이나 java system property와 같은 다른 설정 매커니즘과 달리 언어나 os에 의존하지 않는 표준이다.
4. 백엔드 서비스
- 백엔드 서비스를 연결된 리소스로 취급
- 백엔드 서비스란 애플리케이션 동작 중 network를 통해 이용하는 모든 서비스를 말한다. (ex. MySQL, RabbitMQ, Memcached...)
- Twelve-factor app 은 로컬 서비스와 서드파티 서비스를 구별하지 않는다.
- app 은 local의 mysql 에서 서드파티에서 관리되는 db(ex. Amazon RDS)로 전환할 수 있어야 한다. (리소스 핸들만 변경)
- 하나의 MySQL DB는 하나의 리소스다. 리소스는 자유롭게 배포에 연결되거나 분리될 수 있다.
5. 빌드, 릴리즈, 실행
- 코드베이스는 3단계를 거쳐 배포로 변환한다.
1. 빌드: 실행 가능한 번들로 변환시키는 단계. 종속성을 가져와 바이너리와 에셋들을 컴파일.
2. 릴리즈: 빌드단계에서 만들어진 빌드와 배포의 현재 '설정' 을 결합하는 단계. 완성된 릴리즈는 빌드와 설정을 모두 포함하며 실행환경에서 바로 실행될 수 있도록 준비.
3. 실행: 선택된 릴리즈에 대한 애플리케이션 프로세스의 집합을 시작하여 애플리케이션을 실행환경에서 돌아가도록 한다.
- Twelve-factor app은 빌드, 릴리즈, 실행 단계를 엄격하게 서로 분리 한다.
- 모든 릴리즈는 항상 유니크한 릴리즈 아이디를 지녀야 한다. ex. release timestamp or versioning.
- 릴리즈는 추가만 될 수 있고 변경될 수 없다.
6. 프로세스
- Twelve-factor 프로세스는 무상태(stateless)이며 아무 것도 공유하지 않는다.
- 유지될 필요가 있는 모든 데이터는 데이터베이스와 같은 안정된 백엔드 서비스에 저장되어야 한다.
- 짧은 단일 트랜잭션 내에서 캐시로 프로세스의 메모리 공간이나 파일시스템을 사용해도 된다.
- 웹 애플리케이션 중에서 Sticky Session 에 의존하는 것도 있는데 이는 Twelve-factor를 위반한다. 세션 상태 데이터는 Memcached 나 Redis 처럼 유효기간을 제공하는 데이터 저장소에 저장하는것이 적합하다.
- Sticky Session 이란? 특정 세션의 요청을 처음 처리한 서버로만 전송하는 것을 의미.
로드 밸런싱이 의도한대로 동작하지 않을 수 있으며 특정 서버만 과부하 발생할 수 있다. 특정 서버 Fail 시 해당 서버에 붙어있는 세션들이 모두 소실될 수 있다.
이를 해결하기 위해 세션 클러스터링을 하는데 새로운 서버가 추가 되면 클러스터링 설정에 추가해줘야 하는 단점이 있다.
이를 해결하기 위해 Session server 를 분리(ex. redis server)할 수 있는데 Session server 의 중요성이 올라가고 세션 서버가 죽으면 모든 세션이 사라지기 때문에 다중화도 고려해야 한다.
7. 포트 바인딩
- Twelve-factor app 은 완전히 독립적이며 실행환경에 대한 런타임 인젝션에 의존하지 않는다.
- Twelve-factor app 은 포트를 바인딩하여 http 서비스로 공개되며 그 port로 들어오는 요청을 기다린다.
- 포트 바인딩을 사용한다는 것은 하나의 앱이 다른 앱을 위한 백엔드 서비스가 될 수 있다는 것을 의미한다.
8. 동시성
- 프로세스 모델을 통한 확장이 되어야 한다.
- 프로세스 모델로 제공할 경우 아무것도 공유하지 않고, 수평적으로 확장이 가능하며, 안정적으로 동시성을 높일 수 있다.
- 프로세스는 데몬화해서는 안되며 PID파일을 작성해서는 안된다. 대신 OS의 프로세스 관리자나 Cloud platform의 분산 프로세스 매니저 혹은 Foreman 같은 툴에 의존하여
output stream(ex. 로그) 을 관리하고 충돌이 발생한 프로세스에 대응하고, 재시작과 종료를 처리해야 한다.
9. 폐기 가능
- Twelve-factor app 의 프로세스는 간단하게 폐기 가능하다. (바로 시작하거나 종료될 수 있다)
- 이러한 속성은 신축성 있는 확장과 코드나 설정의 변화를 빠르게 배포하는 것을 쉽게 하고 prod. 배포를 안정성 있게 해준다.
- 프로세스는 시작시간을 최소화 하도록 노력해야 한다.
- 프로세스는 하드웨어 에러에 의한 갑작스러운 죽음에도 견고해야 한다. (Beanstalkd와 같은 견고한 큐잉 벡엔드를 사용하는 것을 권장)
10. dev/prod 일치
- dev, staging, prod 환경을 최대한 비슷하게 유지하여 지속적인 배포가 가능하도록 디자인 해야 한다.
- db, 큐잉 system, cache 와 같은 백엔드 서비스는 dev/prod 일치가 중요한 영역 중 하나이다. (개발환경을 맞춰야 한다.)
11. 로그
- 보통 서버 기반 환경에서 로그는 디스크에 파일형태로 저장한다.
- Twelve-factor app 은 output stream 의 전달이나 저장에 절대 관여하지 않는다. app 은 로그 파일을 작성하거나 관리하려고 해서는 안된다.
- local 개발환경에서 작업중인 개발자는 app의 동작을 관찰하기 원하면 각자의 터미널에 출력되는 이 stream 을 볼 수 있다.
- prod 환경에서는 각 프로세스의 스트림은 하나 이상의 최종 목적지로 전달된다. 이를 위해 오픈 소스 로그 라우터를 사용할 수 있다. (ex. Logplex, Fluentd)
중요한 것은 이 stream 을 splunk같은 로그 분석 시스템과 Hadoop/Hive같은 범용 데이터 보관소에 보낼 수 있다는 것이다.
이러한 시스템은 장기간에 걸쳐 앱의 동작을 조사할 수 있는 강력함과 유연성을 가지게 된다.
. 과거의 특정 이벤트 찾기, 트렌드에 대한 거대한 규모의 그래프 (ex. 분당 요청수) 표현 등
12. Admin 프로세스
- admin/maintenance 작업을 일회성 프로세스로 실행
'IT > 설계' 카테고리의 다른 글
Sequence Diagram (0) | 2013.12.21 |
---|---|
UseCase (0) | 2013.12.21 |