공들여 만든 웹 서비스가 출시 당일, 예상보다 많은 사용자가 몰려 서버가 다운된다면 그보다 아찔한 상황은 없을 것입니다. 서버가 한 번에 얼마나 많은 요청을 처리할 수 있는지, 어느 정도의 동시 접속자 수에서 속도가 느려지는지 미리 파악하는 과정이 바로 **부하 테스트(Load Testing)**입니다.

오늘은 별도의 복잡한 설치 없이 Node.js 환경에서 간편하게 사용할 수 있는 부하 테스트 도구인 Artillery를 활용하여 내 서버의 체력을 측정하는 방법을 알아보겠습니다.


1. 부하 테스트(Load Testing)는 왜 필요한가?

부하 테스트는 단순히 서버를 괴롭히는 것이 아니라, 시스템의 **병목 지점(Bottleneck)**을 찾아내기 위해 수행합니다.

  • 최대 수용 인원 파악: 현재 서버 사양(EC2 인스턴스 등)에서 동시 접속자 몇 명까지 안정적인지 확인합니다.
  • 리소스 부족 지점 발견: CPU가 먼저 차오르는지, 메모리가 부족한지, 혹은 DB 연결 개수가 모자란지 파악합니다.
  • Auto Scaling 기준 수립: 서버가 자동으로 늘어나야 하는 기준(CPU 70% 등)을 정하는 근거가 됩니다.

2. Artillery 설치 및 첫 테스트 시작

Artillery는 YAML 파일로 테스트 시나리오를 작성할 수 있어 매우 직관적입니다.

2.1 설치하기

npm을 통해 전역으로 설치하거나 npx로 바로 실행할 수 있습니다.

Bash
 
npm install -g artillery

2.2 간단한 명령어로 테스트하기

가장 기본적인 테스트는 명령어 한 줄로 가능합니다. 아래는 10명의 가상 사용자가 1초에 1번씩 총 100번의 요청을 보내는 예시입니다.

Bash
 
artillery quick --count 10 -n 100 https://your-api-domain.com

3. 시나리오 기반의 정밀 테스트 (YAML 설정)

실제 서비스와 유사한 환경을 만들기 위해 script.yml 파일을 작성하여 테스트를 수행하는 것이 좋습니다.

YAML
 
config:
  target: "https://api.example.com"
  phases:
    - duration: 60      # 60초 동안 테스트 진행
      arrivalRate: 5    # 초당 5명의 가상 사용자 투입 (평상시 트래픽)
    - duration: 120
      arrivalRate: 5
      rampTo: 50        # 2분 동안 초당 접속자를 50명까지 점진적으로 증가 (피크 타임)
  
scenarios:
  - name: "메인 페이지 접속 및 상품 상세 조회"
    flow:
      - get:
          url: "/"
      - think: 1        # 1초 대기 (사용자 행동 모의)
      - get:
          url: "/products/1"

3.3 테스트 실행 및 리포트 생성

Bash
 
artillery run -o report.json script.yml
# 결과를 HTML 리포트로 변환
artillery report report.json

4. 테스트 결과 해석하기 (지표 읽는 법)

테스트가 끝나면 터미널이나 HTML 리포트에 여러 수치가 나타납니다. 무엇을 중요하게 봐야 할까요?

  • Scenarios created/completed: 생성된 가상 사용자가 요청을 모두 마치고 성공적으로 종료되었는지 확인합니다.
  • RPS (Requests Per Second): 초당 처리량입니다. 서버가 초당 몇 개의 요청을 소화하는지 보여줍니다.
  • Latency (p95, p99): 응답 속도입니다. p95가 500ms라면 전체 사용자 중 95%가 0.5초 이내에 응답을 받았음을 의미합니다. 이 수치가 급격히 올라가면 서버가 힘겨워하고 있다는 신호입니다.
  • HTTP 2xx vs 5xx: 500번대 에러가 발생하기 시작하는 시점이 바로 내 서버의 한계치입니다.

5. 결론: 부하 테스트는 '신뢰'를 만드는 과정입니다

부하 테스트를 마쳤다면, 이제 "우리 서버는 동시 접속자 500명까지는 응답 속도 0.3초를 유지할 수 있습니다"라고 자신 있게 말할 수 있습니다. 수치화된 데이터는 인프라 증설이나 코드 최적화의 명확한 기준이 됩니다.

내 웹사이트의 서버가 한국에 있다면, 미국이나 유럽에 있는 사용자는 사이트 로딩 속도가 현저히 느려질 수밖에 없습니다. 물리적인 거리가 멀수록 데이터가 오가는 시간이 길어지기 때문입니다. 이러한 지연 시간(Latency)을 획기적으로 줄여주는 마법 같은 기술이 바로 **CDN(Content Delivery Network)**입니다.

오늘은 AWS의 강력한 CDN 서비스인 CloudFront를 도입하여 전 세계 어디서나 쾌적한 속도를 보장하고, 서버의 부하를 줄이는 캐싱 전략을 상세히 알아보겠습니다.


1. CloudFront(CDN)란 무엇인가?

CloudFront는 전 세계 곳곳에 흩어져 있는 **엣지 로케이션(Edge Location)**이라는 캐시 서버망을 활용합니다. 사용자가 웹사이트에 접속하면, 한국 서버까지 올 필요 없이 가장 가까운 엣지 로케이션에서 미리 복사해둔 콘텐츠(이미지, JS, CSS 등)를 전달합니다.

1.1 CDN 도입의 주요 이점

  • 로딩 속도 개선: 사용자 근처에서 데이터를 전달하므로 물리적 거리로 인한 지연이 사라집니다.
  • 원본 서버 부하 감소: 대부분의 요청을 CDN이 처리하므로 실제 EC2 서버의 CPU와 대역폭 사용량이 줄어듭니다.
  • 보안 강화: AWS Shield와 연동되어 DDoS 공격을 1차적으로 방어하며, SSL 인증서 적용이 매우 간편합니다.

2. CloudFront 배포(Distribution) 생성하기

이제 내 EC2 서버나 S3 버킷을 원본(Origin)으로 설정하여 CloudFront를 구축해 보겠습니다.

  1. AWS 콘솔에서 CloudFront 서비스로 접속합니다.
  2. [배포 생성] 버튼을 클릭합니다.
  3. 원본 도메인(Origin Domain): 내 EC2의 도메인 주소나 S3 버킷 주소를 선택합니다.
  4. 뷰어 프로토콜 정책: 보안을 위해 Redirect HTTP to HTTPS를 권장합니다.
  5. 캐시 설정: 기본값인 CachingOptimized를 선택하면 AWS에서 권장하는 최적의 캐싱 정책이 적용됩니다.

3. 핵심 캐싱 전략: TTL(Time To Live) 관리

CDN의 핵심은 **"얼마나 오랫동안 데이터를 보관할 것인가?"**입니다. 이를 제어하는 수치가 바로 TTL입니다.

  • 정적 콘텐츠 (이미지, 폰트 등): 내용이 거의 바뀌지 않으므로 TTL을 길게(예: 1년) 설정하여 캐시 효율을 극대화합니다.
  • 동적 콘텐츠 (HTML, JSON 등): 실시간 데이터가 중요하므로 TTL을 짧게 설정하거나, 캐싱을 아예 하지 않도록 설정합니다.

3.1 캐시 무효화 (Invalidation)

만약 이미지를 수정했는데 CDN에 이전 이미지가 남아있다면 어떻게 할까요? 이때 사용하는 기능이 **'무효화(Invalidation)'**입니다. 특정 경로(예: /images/*)를 무효화하면 엣지 로케이션의 데이터를 즉시 삭제하고 원본에서 새 데이터를 가져오게 합니다.


4. Route 53과 CloudFront 연결하기

이제 내가 가진 멋진 도메인으로 접속했을 때 CDN을 거치도록 설정해야 합니다.

  1. Route 53 호스팅 영역으로 이동합니다.
  2. 기존의 A 레코드를 수정하거나 새로 만듭니다.
  3. 별칭(Alias) 스위치를 켭니다.
  4. 트래픽 라우팅 대상: CloudFront 배포에 대한 별칭을 선택하고 생성한 배포 주소를 지정합니다.

5. 결론: 진정한 글로벌 서비스로의 진화

CloudFront 도입은 웹 서비스의 품질을 한 단계 격상시키는 중요한 결정입니다. 단순히 '속도'뿐만 아니라 '비용 절감'과 '보안'까지 챙길 수 있는 일석삼조의 전략이기 때문입니다.

+ Recent posts