GH GambleHub

서킷 브레이커 및 후퇴

서킷 브레이커와 레트라이

1) 왜 필요한가

네트워크는 신뢰할 수 없습니다: 대기 시간 맥동, 노드 하락, 한계에 도달합니다. 배상은 단기 고장에서 저장되며 Circuit Breaker는 계단식 고장 및 자체 DDoS로부터 시스템을 보호합니다. 정확한 타임 아웃 및 한계와의 조합은 SLO를 유지하고 테일 지연과 "nines" 가격을 안정화시킵니다.

2) 기본 원칙

첫 번째 타임 아웃, 후퇴 한 다음 Circuit Breaker.
dempotent 작업 만 재구성하십시오 (GET, dempotent 키가있는 POST/PUT 보안).
재배치 예산을 할당하십시오: 경로 당 원래 RPS의 10-15%.
고장을 현지화하십시오: 벌크 헤드 (별도의 풀/쿼터) + 속도 제한.
분해 중-빠른 고장 (실패), 우아한 분해/스터브.

3) 리트레이 시맨틱

퇴각시기

일시적 오류: 타임 아웃, 5xx, 네트워크 사용 불가, 429 ('재시도 후' 이후).
철회 할 수 없습니다: 명백한 비즈니스 오류 (4xx § 429), dempotence가없는 부작용 (키없는 지불).

전략

지수 백오프 + 지터 (전체 또는 짝수): 재추적 무리를 부드럽게합니다.
최대 시도: 1-2 (드물게 3) -일반적으로 더 많은 것이 유해합니다.
예산: 서비스 당 글로벌 재 트레이 카운터/초 및 요청 당 "재 시도 토큰".
Hedging (희귀): t- 양자 (p95) 이후의 요청의 병렬 이중 - 엄격하게 dempotent 판독에 대해서만.

슈도코드 백오프 + 지터:
python base = 100 # ms for attempt in range(1, max_attempts+1):
try:
return call()
except Transient as e:
if attempt == max_attempts: raise sleep_ms = min(cap_ms, base 2(attempt-1))
sleep(random(0, sleep_ms)) # full jitter

4) 시간 초과 및 "빠른 실패"

클라이언트 타임 아웃 <업스트림 타임 아웃: "좀비" 요청을 누적하지 않도록.
자세한 정보: 시간 초과 연결, 읽기 시간 초과, 전체 마감일.
꼬리 인식 타임 아웃: p95/p99 + 작은 마진을 목표로합니다.
공통 마감일 필드 (예: gRPC '마감일') 를 사용하여 체인 아래로 캐스팅하십시오.

5) 회로 차단기: 작동 방식

상태:
  • 휴무: 트래픽을 통과하고 오류/대기 시간을 계산합니다.
  • 열기: 즉시 거절합니다 (또는 예비 답변).
  • Half-Open: 테스트 쿼리; 성공하면 닫힙니다.
열기 임계 값:
  • 오류/타임 아웃은 창 N 요청/초 당 X% 를 초과하거나 임계 값 이상으로 p99를 초과합니다.
  • 롤링 통계 및 최소 볼륨은 관련이 있습니다 (예: 이하 50 개의 쿼리).

6) 벌크 헤드, 할당량 및 분할 및 정복

업스트림 및 기능 별 연결의 별도 풀.
기내 요청에 대한 쿼터; 불필요한-빠른 거부.
부족한 경우-피처 플래그의 저하.

7) 주변 미터 통합 (Envoy/Istio/Nginx)

특사 (재 시도 + 이상 + CB, 아이디어):
yaml routes:
- match: { prefix: "/api" }
route:
cluster: upstream_api timeout: 2s retry_policy:
retry_on: "connect-failure,reset,retriable-4xx,5xx"
num_retries: 2 per_try_timeout: 600ms retry_back_off: { base_interval: 100ms, max_interval: 800ms }
hedge_policy:
hedge_on_per_try_timeout: true initial_requests: 1 additional_request_chance: { numerator: 5, denominator: HUNDRED } # 5%
clusters:
- name: upstream_api circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 500 max_requests: 1000 max_retries: 200 outlier_detection:
consecutive_5xx: 5 interval: 5s base_ejection_time: 30s max_ejection_percent: 50
Istio (VirtualService 결함/재 시도, 압축 예):
yaml apiVersion: networking. istio. io/v1beta1 kind: VirtualService spec:
hosts: ["payments"]
http:
- route: [{ destination: { host: payments } }]
timeout: 2s retries:
attempts: 2 perTryTimeout: 600ms retryOn: "5xx,connect-failure,refused-stream,reset"
Nginx Ingress (주석):
yaml nginx. ingress. kubernetes. io/proxy-connect-timeout: "2"
nginx. ingress. kubernetes. io/proxy-read-timeout: "2"
nginx. ingress. kubernetes. io/proxy-next-upstream: "error timeout http_502 http_503 http_504"
nginx. ingress. kubernetes. io/proxy-next-upstream-tries: "2"

8) 라이브러리 및 코드 (스택 스 니펫)

자바 (Resilience4j):
java var cb = CircuitBreaker. ofDefaults("psp");
var retry = Retry. of("psp-retry",
RetryConfig. custom()
.maxAttempts(2)
.waitDuration(Duration. ofMillis(200))
.intervalFunction(IntervalFunction. ofExponentialRandomBackoff(100, 2. 0, 0. 5) )//jitter
.retryExceptions(SocketTimeoutException. class, IOException. class)
.build());

Supplier<Response> decorated =
CircuitBreaker. decorateSupplier(cb,
Retry. decorateSupplier(retry, () -> client. call()));

return Try. ofSupplier(decorated)
.recover(BusinessException. class, fallback())
.get();
이동 (컨텍스트 마감일 + 백오프):
go ctx, cancel:= context. WithTimeout(context. Background(), 2time. Second)
defer cancel()
var lastErr error for i:= 0; i < 2; i++ {
reqCtx, stop:= context. WithTimeout(ctx, 600time. Millisecond)
lastErr = call(reqCtx)
stop()
if lastErr == nil { break }
sleep:= time. Duration(rand. Intn(1<<uint(7+i))) time. Millisecond // full jitter time. Sleep(min(sleep, 800time. Millisecond))
}
if lastErr!= nil { return fastFail() }
노드. js (+ p- 재 시도):
js import pRetry from 'p-retry';
await pRetry(() => got(url, { timeout: { connect: 500, request: 2000 } }), {
retries: 2,
factor: 2,
randomize: true,
minTimeout: 100,
maxTimeout: 800,
onFailedAttempt: e => { if (isBusiness(e)) throw e; }
});

9) 재 트레이 및 SLO 예산

타입 재 시도 토큰: 각 리트레이는 토큰을 사용합니다. 수영장은 제한되어 있습니다

오류 예산과 관련하여: 연소율이 임계 값을 초과하면 배상을 끄고 CB를 더 자주 열고 열화를 켜십시오.
카나리아 릴리스: 카나리아에서는 시도와 토큰을 줄이십시오.

10) 헤징 (주의)

p95 마감일 이후에 추가 요청을 실행하여 패자를 취소하십시오.
읽기 및 "안전한" demempotent 작업에만 해당됩니다. 점유율을 제한합니다 (1-5%).
업스트림의 부하 증가를 조심하십시오.

11) 관찰 가능

경로에 따른 RED 지표: 속도, 오류, 지속 시간 (p50/p95/p99).
CB 메트릭: 상태 (개방/반 개방), 개방 속도, 누락/거부 요청.
배상: 시도/요청, 재 시도 속도, 구운 토큰.
주변 측정기: 특이 치 배출, 배출 속도.
추적: 주석으로 '시도', 'cb _ state', '헤지 = 참', 캐스트 'trace _ id'.

12) 아키텍처 통합

각 중요한 업스트림에 대한 벌크 헤드 + CB.
대기열/asynchron: 미친 타임 아웃 대신 긴 작업.
캐시/스터브: 실패시 중요하지 않은 기능을 사용합니다.
Autoscale: 나쁜 휴양지를 보충하지 않습니다. 폭풍을 먼저 멈추십시오.

13) 반 패턴

타임 아웃이없는 배상 → 얼어 붙은 연결 및 수영장 고갈.
비정규 트랜잭션 (이중 상각) 을 반복하십시오.
한도와 지터가없는 무한 지수 성장.

모든 업스트림 → 드래그 앤 드롭 오류에 대한 단일 CB

429 무시/' 재생 후 '.
클라이언트 타임 아웃은 업스트림보다 길다 (또는 전혀 아님).
레트라로 인한 "치료" 비즈니스 오류.

14) 구현 점검표 (0-30 일)

0-7 일

경로와 그 등급을 식별하십시오.
타임 아웃 (연결/읽기/전체) 을 설정하고 최소 배상 (× 1) 및 기본 CB를 활성화하십시오.
메인 업스트림의 풀/할당량 (벌크 헤드) 을 분리하십시오.

8-20 일

지터 및 글로벌 리트레이 예산, 재 시도 속도 경고 포함.
로우 프리오 기능에 대한 빠른 오류, 주변의 이상 배출 설정.
RED + CB/재시도 대시 보드, 태그 트레일.

21-30 일

카나리아 리트레이 프로필 (시도 횟수 감소), 게임 데이 "업스트림 슬로우/플랩".
문서 정책: 누가 복귀, 제한, 예외.
눈이 아닌 데이터에 따라 p95/p99 및 타임 아웃을 검토하십시오.

15) 성숙도 지표

노선의 100% 에는 타임 아웃이 있으며 문서화 된 retray/NE 정책이 있습니다

재시동 속도는 예산에 맞으며 (10-15%) 사고에는 급증이 없습니다.
수영장 전체가 떨어지기 전에 CB가 발사됩니다. 계단식 실패가 없습니다.
트레일은 시도/헤징을 보여줍니다. p99는 피크에서 안정적입니다.

카나리아 릴리스는 "주의" 리트레이 프로파일을 사용합니다

16) 짧은 구성 예

Resilience4j YAML (스프링 부츠, и

yaml resilience4j:
circuitbreaker:
instances:
psp:
slidingWindowType: COUNT_BASED slidingWindowSize: 100 minimumNumberOfCalls: 50 failureRateThreshold: 50 waitDurationInOpenState: 30s permittedNumberOfCallsInHalfOpenState: 5 retry:
instances:
psp:
maxAttempts: 2 waitDuration: 200ms enableExponentialBackoff: true exponentialBackoffMultiplier: 2. 0 retryExceptions:
- java. net. SocketTimeoutException
- java. io. IOException
특허 속도 제한 (아이디어 조각):
yaml rate_limits:
- actions:
- generic_key: { descriptor_value: "api. payments" }

17) 결론

지속 가능성은 규율입니다. 타임 아웃 → 후퇴 (지터 및 예산 포함) → 회로 차단기 + 격벽/할당량 및 빠른 거부. 경계 (이상 배출) 를 설정하고 RED/CB/재시도 대시 보드를 끊고 demempotency 정책을 수정하며 비즈니스 SLI를 잊지 마십시오. 그런 다음 간단한 실패는 보이지 않으며 실제 사건은 계단식 낙하로 바뀌지 않습니다.

Contact

문의하기

질문이나 지원이 필요하시면 언제든지 연락하십시오.우리는 항상 도울 준비가 되어 있습니다!

Telegram
@Gamble_GC
통합 시작

Email — 필수. Telegram 또는 WhatsApp — 선택 사항.

이름 선택 사항
Email 선택 사항
제목 선택 사항
메시지 선택 사항
Telegram 선택 사항
@
Telegram을 입력하시면 Email과 함께 Telegram에서도 답변드립니다.
WhatsApp 선택 사항
형식: +국가 코드 + 번호 (예: +82XXXXXXXXX).

버튼을 클릭하면 데이터 처리에 동의하는 것으로 간주됩니다.