Conversation
There was a problem hiding this comment.
Code Review
This pull request optimizes the k6 load testing scenarios by shortening the ramp-up durations from 9 to 5 minutes and redesigning the circuit breaker test to demonstrate a full state cycle (CLOSED -> OPEN -> HALF_OPEN -> CLOSED) using custom fallback pattern matching. Feedback on these changes suggests improving the PromQL query in the Grafana dashboard to avoid potential parsing errors with label_replace, combining mutually exclusive k6 check conditions to prevent artificially low success rates, and optimizing the recover scenario to skip the final sleep iteration.
| "description": "failed 비율 50% + 5초 지속 시 OPEN 임박. not_permitted 증가 = CB가 OPEN 상태에서 차단 중.", | ||
| "type": "timeseries", | ||
| "targets": [ { "expr": "sum by (name, kind) (rate(resilience4j_circuitbreaker_calls_total[5m]))", "legendFormat": "{{name}} {{kind}}", "refId": "A", "datasource": { "type": "prometheus", "uid": "DS_PROMETHEUS" } } ] | ||
| "targets": [ { "expr": "sum by (name, kind) (rate(resilience4j_circuitbreaker_calls_seconds_count[5m])) or label_replace(sum by (name) (rate(resilience4j_circuitbreaker_not_permitted_calls_total[5m])), \"kind\", \"not_permitted\", \"\", \"\")", "legendFormat": "{{name}} {{kind}}", "refId": "A", "datasource": { "type": "prometheus", "uid": "DS_PROMETHEUS" } } ] |
There was a problem hiding this comment.
PromQL에서 label_replace를 사용하여 고정된 값의 라벨을 추가할 때, src_label과 regex를 빈 문자열("")로 지정하는 방식은 일부 Prometheus 호환 TSDB(예: VictoriaMetrics, Thanos 등)나 구버전 Prometheus에서 파싱 에러를 유발하거나 의도치 않게 동작할 수 있습니다.\n\n안전하고 표준적인 방법은 이미 존재하는 라벨(여기서는 sum by (name)을 통해 보존된 name 라벨)을 src_label로 지정하고, 정규식 ".*"을 매칭시켜 라벨을 추가하는 것입니다.
| "targets": [ { "expr": "sum by (name, kind) (rate(resilience4j_circuitbreaker_calls_seconds_count[5m])) or label_replace(sum by (name) (rate(resilience4j_circuitbreaker_not_permitted_calls_total[5m])), \"kind\", \"not_permitted\", \"\", \"\")", "legendFormat": "{{name}} {{kind}}", "refId": "A", "datasource": { "type": "prometheus", "uid": "DS_PROMETHEUS" } } ] | |
| "targets": [ { "expr": "sum by (name, kind) (rate(resilience4j_circuitbreaker_calls_seconds_count[5m])) or label_replace(sum by (name) (rate(resilience4j_circuitbreaker_not_permitted_calls_total[5m])), \"kind\", \"not_permitted\", \"name\", \".*\")", "legendFormat": "{{name}} {{kind}}", "refId": "A", "datasource": { "type": "prometheus", "uid": "DS_PROMETHEUS" } } ] |
| check(res, { | ||
| 'CB OPEN fallback 감지': () => isCbOpen, | ||
| '정상 LLM 응답': () => isSuccess && !isFallback, | ||
| }); |
There was a problem hiding this comment.
현재 check에 등록된 두 개의 검증 조건('CB OPEN fallback 감지', '정상 LLM 응답')은 서로 배타적(mutually exclusive)입니다. 즉, 정상 응답일 때는 'CB OPEN fallback 감지'가 반드시 실패하고, CB OPEN 상태일 때는 '정상 LLM 응답'이 반드시 실패하게 됩니다.\n\n이로 인해 테스트 실행 후 k6 요약 결과에서 checks 성공률이 인위적으로 낮게 측정되는 문제가 발생합니다.\n\n두 상태 모두 시스템이 의도한 대로 올바르게 동작한 것이므로, 상태 코드(200/201)를 검증하거나 두 조건 중 하나라도 만족하는지 확인하는 단일 check로 통합하는 것이 좋습니다.
check(res, {
'정상 또는 Fallback 응답 (200/201)': () => res.status === 200 || res.status === 201,
});| export function recover() { | ||
| callChat('recover'); | ||
| sleep(3); | ||
| } |
There was a problem hiding this comment.
recover 시나리오는 총 3회의 반복(iterations: 3)으로 구성되어 있으며, 각 반복마다 sleep(3)을 수행합니다. 하지만 마지막 3번째 반복이 완료된 후에는 더 이상 요청을 보낼 필요가 없으므로 3초간 대기하는 것은 불필요하게 테스트 시간을 낭비하고 maxDuration: '30s' 임계치에 아슬아슬하게 도달하게 만듭니다.\n\n따라서 마지막 반복에서는 sleep을 건너뛰도록 최적화하여 테스트 안정성을 높이는 것이 좋습니다.
export function recover() {
callChat('recover');
if (vuIterCount < 3) {
sleep(3);
}
}
📢 기능 설명
필요시 실행결과 스크린샷 첨부
연결된 issue
연결된 issue를 자동을 닫기 위해 아래 {이슈넘버}를 입력해주세요.
close #{이슈넘버}
✅ 체크리스트