인프라 TA를 위한 구글 안티그래비티 성능 테스트 가이드
Terminal Agent 기반 성능 테스트 오케스트레이션
핵심 질문: 안티그래비티로 성능 테스트가 가능한가?
직접적인 답변
안티그래비티는 전통적인 성능 테스트 도구(JMeter, k6, Locust)가 아닙니다.
하지만 성능 테스트 오케스트레이션 플랫폼으로 강력하게 활용할 수 있습니다.
안티그래비티가 할 수 있는 것
1
2
3
4
5
기존 방식:
성능 테스트 스크립트 수동 작성 → 도구 실행 → 결과 수집 → 분석 → 리포트 작성
안티그래비티 방식:
자연어 지시 → AI가 스크립트 자동 생성 → 도구 자동 실행 → 결과 자동 분석 → 리포트 자동 생성
안티그래비티의 역할:
- 테스트 스크립트 자동 생성 (k6, Locust, JMeter)
- 인프라 자동 설정 (Docker, Kubernetes, 모니터링)
- 테스트 실행 오케스트레이션 (Terminal Agent)
- 결과 분석 및 시각화 (Grafana, Prometheus 통합)
- 리포트 자동 생성 (Markdown, HTML)
안티그래비티가 할 수 없는 것
- 자체적으로 가상 사용자를 생성하여 부하 발생 (전문 도구 필요)
- 실시간 부하 분산 (k6, Locust가 수행)
- 복잡한 프로토콜 시뮬레이션 (JMeter가 수행)
결론: 안티그래비티는 성능 테스트의 자동화 레이어입니다.
안티그래비티의 Terminal Agent 이해
Terminal Agent란?
Terminal Agent는 안티그래비티가 시스템의 터미널(bash, PowerShell 등)에 접근하여 명령을 실행할 수 있게 해주는 기능입니다.
할 수 있는 것:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 패키지 설치
npm install k6
pip install locust --break-system-packages
apt install default-jre # JMeter용
# 스크립트 실행
k6 run load-test.js
locust -f locustfile.py --headless -u 100 -r 10
jmeter -n -t test-plan.jmx -l results.jtl
# Docker 컨테이너 실행
docker run --rm -v $PWD:/app grafana/k6 run /app/script.js
# 모니터링 도구 실행
prometheus --config.file=prometheus.yml
grafana-server --config=/etc/grafana/grafana.ini
# 인프라 구성
terraform apply
kubectl apply -f k8s-config.yaml
보안 설정:
- Auto 모드: 에이전트가 안전하다고 판단하면 자동 실행, 위험하면 승인 요청
- Turbo 모드: Deny List에 없으면 모두 자동 실행
- Off 모드: Allow List에 있는 것만 자동 실행
Terminal Agent vs 전통적 CLI
| 전통적 방식 | Terminal Agent |
|---|---|
| 명령어를 정확히 기억해야 함 | 자연어로 요청 |
| 옵션과 플래그를 수동 입력 | AI가 자동으로 적절한 옵션 선택 |
| 에러 발생 시 수동 디버깅 | AI가 에러를 읽고 자동 수정 시도 |
| 스크립트를 순차적으로 실행 | 여러 에이전트가 병렬 실행 |
성능 테스트 도구 선택 가이드
주요 도구 비교
k6 (권장 - 안티그래비티와 가장 궁합이 좋음)
장점:
- JavaScript로 스크립트 작성 (안티그래비티가 생성하기 쉬움)
- CLI 기반으로 Terminal Agent와 완벽 호환
- Grafana와 네이티브 통합 (시각화 용이)
- 경량, 빠름, 리소스 효율적
- CI/CD 통합 쉬움
단점:
- HTTP/WebSocket 중심 (FTP, SMTP 등은 제한적)
- GUI 없음 (하지만 안티그래비티가 보완)
사용 시나리오:
- API 부하 테스트
- 마이크로서비스 성능 검증
- CI/CD 파이프라인 통합
- 클라우드 네이티브 애플리케이션
안티그래비티 통합:
1
2
3
4
"API 엔드포인트 /api/users에 대해
100명의 가상 사용자가 1분 동안 요청하는
k6 스크립트를 작성하고 실행해줘.
결과를 Grafana로 시각화해줘."
Locust (Python 친화적)
장점:
- Python으로 스크립트 작성
- 웹 UI로 실시간 모니터링
- 분산 테스트 쉬움
- 유연한 사용자 시나리오 작성
단점:
- k6보다 리소스 사용량 높음
- 플러그인 생태계가 작음
사용 시나리오:
- 복잡한 사용자 플로우 시뮬레이션
- Python 기반 팀
- 실시간 모니터링이 중요한 경우
안티그래비티 통합:
1
2
3
"로그인 → 상품 검색 → 장바구니 추가 플로우를
시뮬레이션하는 Locust 스크립트를 작성해줘.
500명의 동시 사용자, 분당 50명씩 증가."
JMeter (레거시 지원)
장점:
- 가장 성숙한 도구
- 다양한 프로토콜 지원 (HTTP, FTP, JDBC, SOAP 등)
- 플러그인 생태계 방대
단점:
- Java 기반, 무거움
- GUI 의존적 (자동화 어려움)
- 리소스 소비 많음
사용 시나리오:
- 엔터프라이즈 환경
- 다양한 프로토콜 테스트 필요
- 기존 JMeter 인프라 존재
안티그래비티 통합:
1
2
3
"JMeter로 SOAP API 테스트 계획 생성해줘.
XML 파일 형식으로 저장하고
headless 모드로 실행해줘."
권장 선택 기준
| 상황 | 도구 |
|---|---|
| 현대적 REST API 테스트 | k6 |
| 복잡한 사용자 시나리오 | Locust |
| 다양한 프로토콜 | JMeter |
| CI/CD 통합 우선 | k6 |
| 팀이 Python에 익숙 | Locust |
| 팀이 JavaScript에 익숙 | k6 |
| 레거시 시스템 | JMeter |
실전 1: k6 기반 API 성능 테스트
시나리오: REST API 부하 테스트
목표: 사용자 인증 API가 초당 1,000 요청을 처리할 수 있는지 검증
전통적 방식 (수동)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 1. k6 스크립트 수동 작성 (load-test.js)
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 100 },
{ duration: '5m', target: 100 },
{ duration: '2m', target: 200 },
{ duration: '5m', target: 200 },
{ duration: '2m', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<500'],
},
};
export default function () {
const res = http.post('https://api.example.com/auth/login', {
email: 'test@example.com',
password: 'password123',
});
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1);
}
1
2
3
4
5
6
7
8
# 2. 수동으로 실행
k6 run load-test.js --out json=results.json
# 3. 결과 수동 분석
cat results.json | jq '.metrics'
# 4. 리포트 수동 작성
# (엑셀이나 Google Docs에서 작업)
안티그래비티 방식 (자동화)
Chat Panel에서:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
API 성능 테스트를 수행해줘:
엔드포인트: POST https://api.example.com/auth/login
목표:
- 초당 1,000 요청 처리 능력 검증
- 95 백분위수 응답 시간 < 500ms
테스트 시나리오:
1. 2분간 100 사용자로 램프업
2. 5분간 100 사용자 유지 (안정화)
3. 2분간 200 사용자로 증가
4. 5분간 200 사용자 유지 (피크)
5. 2분간 0으로 램프다운
요청 바디:
{
"email": "test@example.com",
"password": "password123"
}
검증:
- HTTP 상태 코드 200
- 응답 시간 < 500ms (95%)
- 에러율 < 1%
k6로 스크립트 작성하고 실행 후
결과를 HTML 리포트로 생성해줘.
에이전트가 수행하는 작업
Planning Artifact 생성:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## k6 API 성능 테스트 계획
### 1. 환경 준비
- k6 설치 확인 (없으면 설치)
- 테스트 스크립트 생성
### 2. 스크립트 작성
- 파일명: load-test-auth-api.js
- 램프업/다운 로직
- 요청 정의
- 검증 체크
- 임계값 설정
### 3. 실행
- 명령어: k6 run load-test-auth-api.js --out json=results.json
- 실행 시간: 약 16분
### 4. 결과 분석
- results.json 파싱
- 주요 메트릭 추출
- HTML 리포트 생성
예상 소요 시간: 약 20분
Implementation:
- k6 설치 확인
1 2 3 4
# Terminal Agent가 실행 which k6 || brew install k6 # macOS # 또는 which k6 || sudo snap install k6 # Linux
- 스크립트 자동 생성
파일: /home/claude/load-test-auth-api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import http from 'k6/http';
import { check, sleep } from 'k6';
import { htmlReport } from 'https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js';
export const options = {
stages: [
{ duration: '2m', target: 100 }, // Ramp-up to 100 users
{ duration: '5m', target: 100 }, // Stay at 100 users
{ duration: '2m', target: 200 }, // Ramp-up to 200 users
{ duration: '5m', target: 200 }, // Stay at 200 users
{ duration: '2m', target: 0 }, // Ramp-down to 0 users
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% of requests under 500ms
http_req_failed: ['rate<0.01'], // Error rate under 1%
},
};
export default function () {
const url = 'https://api.example.com/auth/login';
const payload = JSON.stringify({
email: 'test@example.com',
password: 'password123',
});
const params = {
headers: {
'Content-Type': 'application/json',
},
};
const res = http.post(url, payload, params);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
'has token': (r) => r.json('token') !== undefined,
});
sleep(1);
}
export function handleSummary(data) {
return {
'summary.html': htmlReport(data),
'summary.json': JSON.stringify(data),
};
}
- 테스트 실행
1 2
# Terminal Agent가 실행 k6 run load-test-auth-api.js --out json=results.json
- 결과 자동 분석 및 리포트 생성
파일: /mnt/user-data/outputs/performance-test-report.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<!DOCTYPE html>
<html>
<head>
<title>API 성능 테스트 리포트</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.metric { background: #f5f5f5; padding: 20px; margin: 10px 0; }
.pass { color: green; font-weight: bold; }
.fail { color: red; font-weight: bold; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
</style>
</head>
<body>
<h1>🚀 API 성능 테스트 리포트</h1>
<div class="metric">
<h2>테스트 개요</h2>
<p><strong>엔드포인트:</strong> POST /auth/login</p>
<p><strong>실행 시간:</strong> 2026-01-22 14:30:00</p>
<p><strong>총 테스트 시간:</strong> 16분</p>
</div>
<div class="metric">
<h2>전체 결과: <span class="pass">✅ PASS</span></h2>
<p>모든 임계값이 충족되었습니다.</p>
</div>
<div class="metric">
<h2>주요 메트릭</h2>
<table>
<tr>
<th>메트릭</th>
<th>값</th>
<th>임계값</th>
<th>결과</th>
</tr>
<tr>
<td>총 요청 수</td>
<td>96,000</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>초당 요청 수 (RPS)</td>
<td>1,024</td>
<td>목표: 1,000</td>
<td class="pass">✅</td>
</tr>
<tr>
<td>평균 응답 시간</td>
<td>245ms</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>95 백분위수 응답 시간</td>
<td>487ms</td>
<td>< 500ms</td>
<td class="pass">✅</td>
</tr>
<tr>
<td>99 백분위수 응답 시간</td>
<td>678ms</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>에러율</td>
<td>0.32%</td>
<td>< 1%</td>
<td class="pass">✅</td>
</tr>
</table>
</div>
<div class="metric">
<h2>응답 시간 분포</h2>
<img src="response-time-chart.png" alt="응답 시간 차트">
</div>
<div class="metric">
<h2>권장사항</h2>
<ul>
<li>✅ API가 목표 성능(1,000 RPS)을 충족함</li>
<li>⚠️ 99 백분위수가 678ms로 높음 - 데이터베이스 인덱스 최적화 권장</li>
<li>✅ 에러율이 낮아 안정적임</li>
<li>💡 피크 시간대 200 사용자까지 안정적으로 처리 가능</li>
</ul>
</div>
</body>
</html>
Walkthrough Artifact:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
## API 성능 테스트 완료
### 실행 요약
- ✅ k6 설치 확인
- ✅ 테스트 스크립트 생성
- ✅ 16분간 테스트 실행
- ✅ 96,000개 요청 완료
- ✅ 결과 분석 및 리포트 생성
### 주요 결과
**모든 임계값 통과 ✅**
- 초당 1,024 요청 처리 (목표 1,000 초과)
- 95% 응답 시간 487ms (목표 < 500ms)
- 에러율 0.32% (목표 < 1%)
### 생성된 파일
- load-test-auth-api.js (테스트 스크립트)
- results.json (원시 데이터)
- summary.html (k6 요약)
- performance-test-report.html (상세 리포트)
### 다음 단계
프로덕션 배포 준비 완료.
필요 시 더 높은 부하(500 사용자) 테스트 권장.
실전 2: Locust 기반 시나리오 테스트
시나리오: E-commerce 전체 플로우
목표: 실제 사용자처럼 로그인 → 검색 → 구매하는 복잡한 플로우 성능 검증
안티그래비티 지시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Locust로 E-commerce 시나리오 테스트 수행:
사용자 플로우:
1. 로그인 (POST /api/auth/login)
2. 상품 검색 (GET /api/products?q=laptop)
3. 상품 상세 조회 (GET /api/products/{id})
4. 장바구니 추가 (POST /api/cart)
5. 결제 (POST /api/checkout)
부하 설정:
- 초기: 10 사용자
- 증가율: 초당 5명
- 최대: 500 사용자
- 실행 시간: 10분
각 단계마다 1-3초 랜덤 대기 (실제 사용자 시뮬레이션)
Locust 스크립트 작성하고 실행 후
웹 UI로 실시간 모니터링 가능하게 해줘.
에이전트 생성 파일
locustfile.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from locust import HttpUser, task, between
import random
class EcommerceUser(HttpUser):
wait_time = between(1, 3) # 1-3초 랜덤 대기
def on_start(self):
"""로그인 (모든 사용자가 시작 시 수행)"""
response = self.client.post("/api/auth/login", json={
"email": "test@example.com",
"password": "password123"
})
self.token = response.json().get("token")
self.headers = {"Authorization": f"Bearer {self.token}"}
@task(5) # 가중치 5 (가장 빈번한 작업)
def search_products(self):
"""상품 검색"""
queries = ["laptop", "phone", "headphone", "monitor"]
query = random.choice(queries)
self.client.get(f"/api/products?q={query}",
headers=self.headers,
name="/api/products?q=[query]")
@task(3) # 가중치 3
def view_product(self):
"""상품 상세 조회"""
product_id = random.randint(1, 100)
self.client.get(f"/api/products/{product_id}",
headers=self.headers,
name="/api/products/[id]")
@task(2) # 가중치 2
def add_to_cart(self):
"""장바구니 추가"""
product_id = random.randint(1, 100)
self.client.post("/api/cart",
json={"product_id": product_id, "quantity": 1},
headers=self.headers)
@task(1) # 가중치 1 (가장 드문 작업)
def checkout(self):
"""결제"""
self.client.post("/api/checkout",
json={
"payment_method": "credit_card",
"address": "123 Main St"
},
headers=self.headers)
실행 스크립트:
1
2
3
4
5
6
7
8
9
10
11
12
# Locust 설치
pip install locust --break-system-packages
# 실행 (웹 UI 포함)
locust -f locustfile.py --host=https://api.example.com \
--users 500 --spawn-rate 5 --run-time 10m \
--html locust-report.html
# 또는 headless 모드 (자동화용)
locust -f locustfile.py --host=https://api.example.com \
--users 500 --spawn-rate 5 --run-time 10m \
--headless --html locust-report.html --csv locust-stats
모니터링:
1
2
3
4
5
6
7
웹 UI가 http://localhost:8089에서 실행 중입니다.
실시간으로 다음을 확인할 수 있습니다:
- 현재 사용자 수
- 초당 요청 수 (RPS)
- 응답 시간 차트
- 실패율
- 각 엔드포인트별 통계
실전 3: 인프라 모니터링 통합
시나리오: Prometheus + Grafana 자동 설정
목표: 성능 테스트 중 서버 메트릭 실시간 모니터링
안티그래비티 지시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
성능 테스트를 위한 모니터링 스택을 구성해줘:
1. Prometheus 설정
- k6 메트릭 수집
- 서버 메트릭 수집 (CPU, 메모리, 네트워크)
2. Grafana 설정
- Prometheus 데이터소스 연결
- k6 대시보드 자동 import
- 서버 메트릭 대시보드 생성
3. Docker Compose로 모두 실행
모든 설정 파일을 생성하고
한 명령어로 전체 스택을 시작할 수 있게 해줘.
에이전트 생성 파일
docker-compose.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_INSTALL_PLUGINS=grafana-k6-app
volumes:
- grafana-data:/var/lib/grafana
- ./grafana-datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml
- ./grafana-dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yml
depends_on:
- prometheus
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
ports:
- "9100:9100"
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
volumes:
prometheus-data:
grafana-data:
prometheus.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
# k6 메트릭 (k6를 --out experimental-prometheus-rw로 실행 시)
- job_name: 'k6'
static_configs:
- targets: ['host.docker.internal:5656']
# 서버 메트릭
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
# 애플리케이션 메트릭 (있다면)
- job_name: 'app'
static_configs:
- targets: ['app-server:8080']
grafana-datasources.yml:
1
2
3
4
5
6
7
8
9
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
k6 실행 스크립트 (Prometheus 통합):
1
2
k6 run load-test.js \
--out experimental-prometheus-rw=http://localhost:9090/api/v1/write
실행 가이드:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 전체 스택 시작
docker-compose up -d
# 상태 확인
docker-compose ps
# Grafana 접속: http://localhost:3000 (admin/admin)
# Prometheus 접속: http://localhost:9090
# k6 테스트 실행 (Prometheus에 메트릭 전송)
k6 run load-test.js \
--out experimental-prometheus-rw=http://localhost:9090/api/v1/write
# 종료
docker-compose down
실전 4: CI/CD 통합
시나리오: GitHub Actions로 자동 성능 테스트
목표: 코드 배포 전 자동으로 성능 회귀 테스트
안티그래비티 지시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GitHub Actions workflow를 만들어줘:
트리거:
- main 브랜치에 PR 생성 시
- nightly (매일 자정)
작업:
1. 스테이징 환경 배포
2. k6로 성능 테스트 실행
3. 임계값 검증
4. 실패 시 PR 차단
5. 결과를 PR 코멘트로 게시
임계값:
- 95% 응답 시간 < 500ms
- 에러율 < 1%
- 이전 결과 대비 응답 시간 10% 이상 증가 시 경고
에이전트 생성 파일
.github/workflows/performance-test.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
name: Performance Test
on:
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * *' # 매일 자정
jobs:
performance-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup k6
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: Deploy to Staging
run: |
# 스테이징 배포 로직
./deploy-staging.sh
env:
STAGING_API_KEY: $
- name: Wait for deployment
run: sleep 60 # 배포 완료 대기
- name: Run k6 performance test
run: |
k6 run tests/performance/load-test.js \
--out json=results.json \
--env STAGING_URL=$
- name: Parse results
id: parse
run: |
# 결과 파싱 및 임계값 검증
python3 scripts/parse-k6-results.py results.json > summary.txt
# 이전 결과와 비교
python3 scripts/compare-results.py results.json baseline.json > comparison.txt
- name: Check thresholds
run: |
# 임계값 초과 시 실패
if grep -q "THRESHOLD_EXCEEDED" summary.txt; then
echo "❌ 성능 임계값 초과"
exit 1
fi
# 10% 이상 성능 저하 시 경고
if grep -q "PERFORMANCE_DEGRADATION" comparison.txt; then
echo "⚠️ 성능 저하 감지"
fi
- name: Comment PR
uses: actions/github-script@v6
if: github.event_name == 'pull_request'
with:
script: |
const fs = require('fs');
const summary = fs.readFileSync('summary.txt', 'utf8');
const comparison = fs.readFileSync('comparison.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 🚀 성능 테스트 결과\n\n${summary}\n\n### 📊 이전 결과 대비\n\n${comparison}`
})
- name: Upload results
uses: actions/upload-artifact@v3
if: always()
with:
name: performance-results
path: |
results.json
summary.txt
comparison.txt
- name: Update baseline
if: github.ref == 'refs/heads/main'
run: |
# main 브랜치 merge 시 baseline 업데이트
cp results.json baseline.json
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add baseline.json
git commit -m "Update performance baseline"
git push
scripts/parse-k6-results.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import json
import sys
def parse_results(results_file):
with open(results_file) as f:
data = json.load(f)
metrics = data['metrics']
# 주요 메트릭 추출
p95 = metrics['http_req_duration']['values']['p(95)']
error_rate = metrics['http_req_failed']['values']['rate']
rps = metrics['http_reqs']['values']['rate']
# 임계값 검증
thresholds_passed = True
print("### 주요 메트릭")
print(f"- **RPS**: {rps:.2f} requests/sec")
print(f"- **P95 응답 시간**: {p95:.2f}ms")
print(f"- **에러율**: {error_rate*100:.2f}%")
print()
if p95 > 500:
print("❌ THRESHOLD_EXCEEDED: P95 > 500ms")
thresholds_passed = False
if error_rate > 0.01:
print("❌ THRESHOLD_EXCEEDED: 에러율 > 1%")
thresholds_passed = False
if thresholds_passed:
print("✅ 모든 임계값 통과")
return thresholds_passed
if __name__ == "__main__":
passed = parse_results(sys.argv[1])
sys.exit(0 if passed else 1)
베스트 프랙티스
1. 테스트 환경 격리
1
2
3
4
프로덕션과 동일한 스펙의 스테이징 환경에서 테스트
- 프로덕션 데이터 사용 금지
- 별도의 데이터베이스 인스턴스
- 네트워크 분리
2. 점진적 부하 증가
1
2
3
4
❌ 나쁜 예: 0 → 1000 사용자 즉시
✅ 좋은 예: 0 → 100 → 300 → 500 → 1000 단계적 증가
이유: 시스템이 적응할 시간을 주고, 정확한 임계점 파악
3. 현실적인 시나리오
1
2
3
4
5
6
❌ 나쁜 예: 모든 사용자가 동일한 동작 반복
✅ 좋은 예:
- 70% 브라우징만
- 20% 검색 + 브라우징
- 10% 구매까지 완료
- 사용자마다 1-5초 랜덤 대기
4. 모니터링 필수
1
2
3
4
5
6
7
성능 테스트 중 반드시 모니터링:
- CPU 사용률
- 메모리 사용률
- 디스크 I/O
- 네트워크 대역폭
- 데이터베이스 커넥션 풀
- 응답 시간 분포
5. 베이스라인 유지
1
2
3
첫 테스트 결과를 베이스라인으로 저장
이후 모든 테스트를 베이스라인과 비교
10% 이상 성능 저하 시 자동 경고
안티그래비티 한계와 대안
안티그래비티가 어려운 것
- 매우 복잡한 분산 테스트
- 수천 대의 머신에서 동시 실행
- 대안: BlazeMeter, AWS DevOps Guru 같은 전문 플랫폼
- 실시간 대화형 조정
- 테스트 중 실시간으로 부하 조정
- 대안: Locust 웹 UI 직접 사용
- 매우 특수한 프로토콜
- MQTT, CoAP, gRPC 등
- 대안: 해당 프로토콜 전용 도구 + 안티그래비티로 스크립트 생성
권장 하이브리드 접근
1
2
3
4
1. 안티그래비티로 스크립트 초안 생성
2. 필요 시 수동으로 미세 조정
3. 안티그래비티로 실행 및 분석
4. 복잡한 경우 전문 도구 직접 사용
결론
구글 안티그래비티는 직접적인 성능 테스트 도구는 아니지만, 성능 테스트 자동화의 강력한 오케스트레이터입니다.
핵심 가치:
- 테스트 스크립트 작성 시간 90% 단축
- 인프라 설정 자동화
- 결과 분석 및 리포팅 자동화
- CI/CD 통합 간소화
- 여러 도구(k6, Locust, JMeter)를 통합 관리
인프라 TA의 역할 변화:
1
2
3
4
기존: 스크립트 작성 + 실행 + 분석 + 리포트
안티그래비티 활용: 요구사항 정의 + 검증 + 의사결정
저수준 작업은 AI에게, 고수준 판단은 사람이
시작하기:
- k6로 간단한 API 테스트부터 시작
- 안티그래비티에게 스크립트 생성 요청
- 결과 검토 후 점진적으로 복잡한 시나리오로 확장
- Workflow로 표준화하여 팀 전체 활용
성능 테스트의 미래는 “스크립트를 작성하는 것”이 아니라 “시스템의 성능 목표를 정의하고 검증하는 것”입니다. 안티그래비티는 그 전환을 가능하게 합니다.
문서 작성 일자: 2026-01-22