스타트업을 만들었다. → 좀…..잘되네? → 사용자 증가
일반적인 Node.js 애플리케이션 - 단일 스레드 컨텍스트
단일 스레드에서의 용량은 제한됨
→ 고부하 애플리케이션에서는 여러 프로세스와 시스템에 걸친 확장 필요
➕ 고가용성, 장애 내성 같은 좋은 속성
시간이 지남에 따라 ‘확장 가능한’ 아키텍처도 중요하다.
확장성의 첫번째 기본원칙 - ‘부하 분산’
X - 복제
Y - 서비스/기능별 분해
Z - 데이터 파티션으로 분할
Starting Point - 모놀리식 애플리케이션
단일 스레드 → 전통적 웹 서버에 비해 빠른 확장 요구
단점인가? 확장의 강제 → 가용성과 내결함성에 유익한 효과
각 인스턴스의 공유할 수 없는 리소스(메모리, 디스크 등)에 저장하지 않고 공유DB를 사용해야 함
가장 간단한 패턴
새 인스턴스 분기를 단순화 하고 부하를 배분
확장한 애플리케이션의 인스턴스를 나타내는 작업 프로세스 생성, 연결 분산
시스템에서 사용가능한 CPU의 수만큼 작업자 생성
대부분 라운드로빈 로드 밸런싱 알고리즘(순환 방식) 사용
windows 제외한 모든 플랫폼에서 기본
cluster.schedulingPolicy , cluster.SCHED_RR, cluster.SCHED_NONE 설정해 전역적으로 수정가능
server.listen() 에 대한 모든 호출은 마스터 프로세스 담당
마스터 프로세스는 이를 작업자 풀에 배포
server.listen({id}): 작업자가 특정 파일 설명자를 사용해 수신하는 경우server.listen(handle): 작업자가 명시적인 핸들 객체를 수신server.listen(0): 서버가 임의의 포트에서 수신pid가 포함된 메시지로 응답
프로세스가 하나로, pid 계속 동일
빈 루프는 CPU부하 시뮬레이션 위해
작업자들은 별도의 프로세스로 필요에 따라 생성과 소멸
오작동, 충돌 발생해도 서비스 유지 가능 - 복원력
하나의 인스턴스 다운 → n-1개의 인스턴스가 처리하면 된다
직관적으로 보면 가용성이 100이 나올 것 같지만 이미 설정된 연결의 중단시 실패 → 그래도 높은 가용성
새 버전 릴리즈시 클러스터 없이는 작은 간격 동안 요청 처리가 불가
전문 애플리케이션이나 CI/CD에 의한 잦은 재배포시 문제가 될 수 있음
클러스터를 활용해 하나의 프로세스씩 재배포하는 것이 가능하다
클러스터 모듈은 상태 저장이 필요한 통신에서는 정상작동 X
ex) 클러스터의 인스턴스 A에서 인증, 다음 요청은 B 인스턴스에 전달된다면? B는 인증 정보가 없는데?
클러스터 사용의 대안
다른 포트 또는 물리머신에서 실행되는 여러 독립적 인스턴스를 시작
역방향 프록시(또는 게이트웨이)를 사용해 해당 인스턴스에 접근하도록
역방향 프록시는 로드 밸런서로도 사용
단일 시스템에서는 클러스터로 수직 확장
그런 시스템 여러개를 이용하는 역방향 프록시의 수평 확장
Nginx, HAProxy, Node.js 기반 프록시, 클라우드 기반 프록시
클러스터 없이 쓸 수 없는 기능 - 충돌 시 자동 재시작
하지만 외부 프로세스 쓰면 해결!
forever, pm2 - node 기반
systemd, runit - OS 기반
monit, supervisord - 고급 모니터링 솔루션
Kubernetes, Nomad, DockerSwarm - 컨테이너 기반
클라우드의 장점 - 현재/예측된 트래픽을 기반으로 ‘동적 확장’
서비스 레지스트리 - 실행중인 서버와 서비스를 추적하는 저장소

서비스 각각이 데이터 소유권을 지님
→ 시스템의 일관성을 위해 더 많은 통신이 필요
모든 노드를 연결해야 하는데… 어떻게 연결하지?
앞에서 이야기 한 패턴, API프록시가 url경로에 따라 서비스에 연결됨 (단순한 분산 아키텍처?)
다양한 서비스를 명시적으로 통합하는 추상화 계층
서비스에 의해 만들어진 것과 다른 API를 노출 시키고, 추가적인 기능 분할을 가능케 함
서로 다른 서비스의 데이터를 단일 응답으로 결합 시킬 수 있음
오케스트레이터는 너무 많은 것을 수행하는 God객체가 될 수 있다 → 높은 결합, 낮은 응집력, 높은 복잡성
서비스간의 직접적인 연결을 하되 모든 서비스는 분리된 상태 - 메시지 브로커와 발행/구독 패턴