-
이코에코(Eco²) Eventual Consistency #2: ext-authz 2500 VUs 부하 테스트이코에코(Eco²)/Eventual Consistency 2025. 12. 30. 12:11
테스트 실행: Locust VUs 2500/ramp-ups: 250, Observability: Prometheus/Grafana, Locust
1. 테스트 환경
https://snapshots.raintank.io/dashboard/snapshot/JbEhJRXD1vCt77ZOfCxy9N72wXJ3ZyKj
Grafana
If you're seeing this Grafana has failed to load its application files 1. This could be caused by your reverse proxy settings. 2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath. If not using a reverse proxy m
snapshots.raintank.io
항목 값 테스트 시간 2025-12-30 11:27:26 ~ 11:45:43 KST (18분) 테스트 도구 Locust (2,500 VU) 엔드포인트 /api/v1/authz/ping(Istio DirectResponse)ext-authz Pods 2 → 4 (HPA auto-scale) 노드 k8s-api-auth (2 vCPU, 2GB) 테스트 구성:
┌─────────────────────────────────────────────────────────────────────────┐ │ Load Test Architecture │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ Locust (2,500 VU) │ │ │ │ │ │ HTTPS (Bearer Token) │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Istio Gateway │ │ │ └────────┬────────┘ │ │ │ │ │ │ gRPC (ext-authz) │ │ ▼ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ ext-authz Pod 1 │ ... │ ext-authz Pod 4 │ (HPA: 2→4) │ │ └────────┬────────┘ └────────┬────────┘ │ │ │ │ │ │ │ Local Cache (O(1)) │ │ │ └───────────────────────┘ │ │ │ │ ✅ Redis 호출 없음 (100% 로컬 캐시) │ │ │ └─────────────────────────────────────────────────────────────────────────┘
2. 처리량 (Throughput)
2.1 RPS Summary
메트릭 값 소스 Locust RPS ~1,500 req/s Locust UI Prometheus Max RPS 1,477 req/s sum(rate(ext_authz_requests_total[1m]))Prometheus Avg RPS 798 req/s 18분 평균 2.2 RPS Timeline (Prometheus)
Time (KST) | RPS ---------------|-------- 11:27:30 | 994 11:28:00 | 1,257 11:28:30 | 1,356 11:29:00 | 1,486 ← Peak 11:29:30 | 1,299 11:30:00 | 284 ← 노드 포화 ... | 0 ← 잠시 중단 11:32:00 | 1,319 11:32:30 | 1,424 11:33:00 | 1,312 ... | ~1,340 ← 안정화 11:41:30 | 1,143 11:42:00 | 324 ← 테스트 종료 시작
3. 레이턴시 분석
3.1 전체 요청 레이턴시 (ext-authz gRPC)
메트릭 Max Avg p99 275.5ms 157.4ms Avg 24.4ms 16.5ms 3.2 컴포넌트별 레이턴시
컴포넌트 p99 Max p99 Avg 비중 JWT Verify 7.2ms 6.5ms ~40% Cache Lookup 2.3µs 2.2µs ~0.01% gRPC/Network ~268ms ~150ms ~60% 3.3 레이턴시 분석
┌─────────────────────────────────────────────────────────────────────────┐ │ p99 Latency 분해 (max 275.5ms) │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────────────┐ │ │ │ gRPC/Network: ~268ms (97.3%) │ │ │ └──────────────────────────────────────────────────────────────────┘ │ │ ┌───────┐ │ │ │JWT 7ms│ (2.6%) │ │ └───────┘ │ │ │ Cache: 2.3µs (0.0008%) │ │ │ │ ✅ 로컬 캐시로 인한 지연: 무시 가능 (< 3µs) │ │ ⚠️ 병목: Istio/gRPC 네트워크 오버헤드 │ │ │ └─────────────────────────────────────────────────────────────────────────┘
4. 로컬 캐시 성능
4.1 캐시 메트릭
메트릭 값 설명 Cache Lookups 845,914 전체 조회 수 Cache Lookup p99 2.3µs p99 레이턴시 Cache Hits 0 테스트 토큰은 블랙리스트 아님 Cache Misses 845,914 정상 토큰 (allow) Cache Evictions 0 TTL 만료 없음 4.2 Redis 비교
항목 로컬 캐시 Redis 개선 p99 Latency 2.3µs ~2ms 870배 네트워크 호출 0 845,914 제거
5. 리소스 사용량
5.1 HPA Scaling
시간 Pods CPU 상태 시작 2 정상 11:29 4 노드 포화 (100%) 종료 4 유지 5.2 노드 리소스
메트릭 값 Node k8s-api-auth CPU 2 vCPU (100% 도달) Memory 2GB (86% 사용)
6. MQ 상태
메트릭 값 Connection Status 1 (Connected) Events Received 0 (테스트 중 로그아웃 없음) Events Failed 0 Reconnects 0
7. 결론

7.1 성능 요약
항목 결과 최대 RPS 1,477 req/s (Prometheus) 평균 RPS 798 req/s p99 Latency 275.5ms (max) 캐시 p99 2.3µs Redis 호출 0 7.2 병목 분석
1. 노드 CPU 포화 (2 vCPU, 100%) └── ext-authz 4 pods가 노드 한계 도달 2. Istio/gRPC 네트워크 오버헤드 (~97% of latency) └── ext-authz 자체 처리 시간 < 10ms 3. 로컬 캐시: 병목 아님 (2.3µs) └── Redis 대비 870배 빠름7.3 권장 사항
개선 예상 효과 노드 스케일아웃 RPS 노드수 배수로 증가 ext-authz 노드 분리 격리된 리소스 확보 Istio 튜닝 p99 레이턴시 감소
8. 테스트 명령어
8.1 Locust
# Web UI TOKEN="<jwt>" locust -f locustfile_authz.py --host https://api.dev.growbin.app # Headless TOKEN="<jwt>" locust -f locustfile_authz.py --headless -u 2500 -r 250 -t 18m \ --host https://api.dev.growbin.app8.2 Prometheus 쿼리
# RPS sum(rate(ext_authz_requests_total[1m])) # p99 Latency histogram_quantile(0.99, sum(rate(ext_authz_request_duration_seconds_bucket[1m])) by (le)) * 1000 # Cache Lookup p99 histogram_quantile(0.99, sum(rate(ext_authz_blacklist_cache_lookup_duration_seconds_bucket[1m])) by (le)) * 1000000 # JWT Verify p99 histogram_quantile(0.99, sum(rate(ext_authz_jwt_verify_duration_seconds_bucket[1m])) by (le)) * 1000
9. References
'이코에코(Eco²) > Eventual Consistency' 카테고리의 다른 글
이코에코(Eco²) Eventual Consistency #4: Blacklist Relay Worker 구현 (0) 2025.12.30 이코에코(Eco²) Eventual Consistency #3: ext-authz 로컬 캐시 일관성 보장 설계 (0) 2025.12.30 이코에코(Eco²) Eventual Consistency #1: ext-authz Blacklist 로컬 캐시 및 Fanout 구현 (0) 2025.12.30 이코에코(Eco²) Eventual Consistency #0: ext-authz 로컬 캐싱 설계 (0) 2025.12.29