B2B SaaS Architecture(Single Region)

ejlieb·2024년 3월 5일

DevOps

목록 보기
1/2

개요

B2B SaaS Architecture는 일반적인 B2C SaaS Architecture와 다른 점을 지닌다.

그 중에서도 가장 고려해서 설계했던 부분은 2가지이다.

  • 사용자별 버전 유지
    • 버전에 따라 파싱 결과가 달라질 수 있기 때문에, 보수적인 B2B SaaS 제품 특성상, 한번 사용한 버전에서의 업데이트를 기피하는 경향이 있다. 따라서, 각 사용자(회사)마다 독립적인 버전을 유지할 수 있도록 설계해야 한다.
  • DB 격리
    • 개인 사용자에 비해, 민감한 DB 데이터가 많은 기업 특성 상, DB에 대한 물리적인 격리를 동반하기로 결정하였다.

따라서 두가지 조건을 지키기 위한 Silo 모델이 B2B 아키텍처에 적합하다고 판단한다.

싱글 리전 설계는 단일 리전에 대한 프로비저닝을 구현하여 테스트 하기 위한 아키텍처이다.

전체 아키텍처

Silo 모델

  • Silo 모델은 어떤 리소스가 하나의 테넌트에게 할당되는 아키텍처이다. 흔히 사용하는 Pooled 모델이 멀티 테넌시 개념을 기반으로, 하나의 리소스를 스케일링 해가며 공유하는 것에 반한다.
  • 하지만 동시에 Silo 모델은 멀티-테넌시 한데, Silo 모델을 Onboarding하는 절차와 이를 수행하는 identity, 그리고 이를 관장하는 Construct는 테넌트에게 동일하기 때문이다.

Control Plane

  • 컨트롤 플레인은 Core 프로덕트를 온보딩하고, 프로비저닝하고, 모니터링하는 일종의 어플리케이션이다.
  • 컨트롤 플레인은 Core와 관련된 데이터를 저장하지 않고, 오직 Core를 관리하기 위한 목적이기 때문에 Pooled Model로 설계할 수 있다.
  • Cloudfront를 통해 S3 Bucket의 정적 에셋(FE)를 Deploy 하기 위한 Distribution을 생성한다.
  • Cloudfront의 루트 behavior(’/’)는 S3 Origin을, api behavior(’/api’)는 Api gateway origin을 바라본다. 이를 통해 일종의 리버스 프록시(L7)를 구현할 수 있다.
  • Api gateway에서는 각각의 Path에 따라 Method를 나누고, 각각의 Intergration Target을 각 Api Module 람다로 설정한다. 컨트롤 플레인의 기능에 따라, 유저, 온보딩(프로비저닝), 모니터링 등등의 API가 존재해야 한다.
  • API에서 핸들링하는 데이터의 종류에 따라, RDB 또는 Nosql을 선택하여 DB를 프로비저닝 한다. 대부분의 경우 Key-value의 DynamoDB를 사용할 수 있다.
  • 만약 자체적인 인증/인가 로직을 개발하지 않는다면 AWS Cognito를 통해 User pool을 생성하여 관리한다.

Core Product

  • Control Plane을 통해 Core Product를 온보딩하고 프로비저닝 한다.

  • Core Product의 구성에 따라 Core를 구성한다. 위의 예시는 2개의 백엔드 모듈과 하나의 프론트엔드로 구성된 어플리케이션의 예시이다.
  • Nginx로 서빙하는 Frontend가 Application Load Balancer를 통해 백엔드와 통신한다. 백엔드에는 원하는 저장 공간을 붙여 사용할 수 있다.(EFS, S3 등등)
  • Database의 경우 Computing 환경에 직접 띄울 수도, AWS Native Service를 사용할 수도 있다.
  • 컨테이너 환경으로 구성하고 싶으면 ECS 또는 EKS를 사용할 수 있다. 아래는 ECS로 구성하는 예이다.

  • ECS Cluster를 생성한다.
  • Service를 정의한다. Service의 Security Group과 Task Definition을 정의하고, Auto Scaling Group을 생성한다.
  • Auto Scaling에 대한 Config를 세팅하여, min, max 스케일링 범주를 설정하고, 어떤 지표에 따라 스케일링 할 지 결정한다.
  • Scaling 되며 Task Container가 생성되고, 삭제된다.
  • ALB를 통해 각각의 Task Container로 라우팅한다.
  • 만약 Batch Job과 같이, 항시 떠있을 필요가 없는 경우, Service의 형태가 아니라 Task Definition을 통해 개별 Task로 필요한 시점에 띄울 수 있다.

0개의 댓글