Repository navigation
feat: Feign 내부 호출에 서킷브레이커를 건다 - #85
Merged
Merged
Conversation
타임아웃(#78)만으로는 피호출 서비스가 죽어 있는 동안에도 모든 요청이 매번 타임아웃까지 기다린다. Resilience4j 서킷브레이커를 붙여 실패가 쌓이면 호출을 즉시 차단하고 503 으로 응답한다. - 브레이커는 메서드가 아니라 Feign 클라이언트(name) 단위로 묶는다. 내부 호출은 메서드별 트래픽이 적어 기본(메서드 단위) 네이밍으로는 minimum-number-of-calls 에 도달하지 못해 브레이커가 열리지 않는다. - 4xx 는 실패로 세지 않는다. 비즈니스 에러가 브레이커를 열면 멀쩡한 서비스로 가는 호출까지 차단된다. - 스레드풀 실행을 꺼서 Spring Cloud 기본 TimeLimiter(1s)가 read-timeout 보다 먼저 호출을 끊는 것을 막는다. - 폴백 없는 호출의 예외가 NoFallbackAvailableException 으로 래핑되는 문제는 프록시 단계 언랩퍼로 원본 예외를 복원한다. 기존 catch (FeignException) 분기가 그대로 동작한다. - 브레이커 open / 타임아웃은 503(GEN-105) 으로 내린다. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 26, 2026
popeye0618
added a commit
that referenced
this pull request
Aug 26, 2026
common-module 변경 PR(#85)의 자동 리뷰가 9분 넘게 걸렸다. CLAUDE.md 의 "서비스 경계를 넘는 변경은 하위 호환성을 특히 주의해서 본다" 지침을 따라 diff 밖의 다른 서비스 소비 코드까지 찾아 읽었기 때문으로 보인다 - diff 자체는 403줄로 크지 않았다. 자동 리뷰(claude-code-review.yml)는 diff 에 나온 코드만 보게 프롬프트로 범위를 좁히고, common-module/내부 API/Kafka 스키마 변경이 보이면 실제 분석 대신 "@claude 로 수동 리뷰를 요청하라"는 코멘트만 남기도록 한다. cross-service 하위 호환성 분석은 claude.yml(@claude 수동 호출)의 역할로 문서화한다. allowedTools 는 건드리지 않았다 - #79 에서 도구를 뺐다가 리뷰가 통째로 증발한 사고가 있어서, 속도 문제는 프롬프트로만 좁힌다.
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
배경
Feign 안정화 Phase 2. 타임아웃(#78)만으로는 피호출 서비스가 죽어 있는 동안에도 모든 요청이 매번 타임아웃(1~5초)까지 기다린다. Resilience4j 서킷브레이커를 붙여 실패가 쌓이면 호출을 즉시 차단하고 503으로 응답한다.
변경 내용
서킷브레이커 (
feign-resilience.yml)spring-cloud-starter-circuitbreaker-resilience4j추가,spring.cloud.openfeign.circuitbreaker.enabled: trueignore-exceptions: FeignException$FeignClientException) — 없는 리소스 404 같은 비즈니스 에러가 브레이커를 열면 멀쩡한 서비스로 가는 호출까지 차단된다.설계 결정 3가지
InternalFeignConfig의CircuitBreakerNameResolver). 기본 네이밍은 메서드 시그니처 단위라 내부 호출처럼 트래픽이 적으면 minimum-number-of-calls에 도달하지 못해 브레이커가 영영 열리지 않는다. 장애는 엔드포인트가 아니라 프로세스 단위로 온다.disable-thread-pool: true). 켜두면 Spring Cloud 기본 TimeLimiter(1s)가 read-timeout(3~5s)보다 먼저 호출을 끊고, EC2 한 대 6 JVM 전제에서 서비스마다 스레드풀이 하나씩 늘어난다. 끄면 Feign read-timeout이 유일한 시간 상한이다.FeignCircuitBreakerExceptionUnwrapper). 서킷브레이커를 켜면 폴백 없는 호출의 모든 예외가NoFallbackAvailableException으로 래핑되는데, 그대로 두면 기존catch (FeignException)분기(예:AdminUserItemServiceImpl의 404→비즈니스 에러 변환)가 컴파일 에러 없이 조용히 무력화된다. 프록시 단계에서 cause를 복원해 호출부는 도입 전과 같은 예외를 받는다.실패 응답 (
GlobalExceptionHandler,GeneralErrorCode)CallNotPermittedException)과 연결 실패·타임아웃(RetryableException)을 503 + GEN-105로 내린다. 기존 FeignException 응답 패스스루는 그대로다.부수 정리
resilience4j_circuitbreaker_*). health indicator는 의도적으로 켜지 않았다 — 브레이커 open이/actuator/health를 DOWN으로 만들면 헬스체크가 멀쩡한 컨테이너를 재시작시키는 2차 장애가 된다.검증
FeignCircuitBreakerTest— 실제 HTTP 서버(JDK 내장, 루프백)를 상대로 운영 파일(feign-resilience.yml) 그대로를 물려 실증:전 모듈 단위 테스트 통과(서비스 컨텍스트 부팅 테스트들이 새 설정을 물고 정상 로드됨).
하위 호환성
CallNotPermittedException(503) 뿐이다.🤖 Generated with Claude Code