gRPC 상태 코드별 재시도 기준
UNAVAILABLE 같은 일시적 장애만 retryPolicy로 재시도하고, 요청 오류를 나타내는 코드에는 재전송하지 않는다.
재시도 대상 판별
실패한 요청을 그대로 재전송하여 결과가 개선되는 경우는 일부에 한정된다. 상태 코드가 그 구분을 나타낸다.
| 상태 코드 | 의미 | 재시도 |
|---|---|---|
UNAVAILABLE |
서비스 일시 사용 불가 | 간격을 증가시키며(backoff) 재시도 |
ABORTED |
동시성 충돌로 중단 | 해당 호출만이 아니라 앞 단계부터 재시도 |
FAILED_PRECONDITION |
시스템 상태 부적합 | 상태를 수정한 뒤에만 |
DEADLINE_EXCEEDED |
기한 초과 | 서버가 처리를 완료했을 수 있으므로 멱등한 호출만 |
INVALID_ARGUMENT, UNIMPLEMENTED |
요청 오류 또는 미구현 기능 | 재시도해도 결과 동일 |
멱등(idempotent)은 여러 번 처리해도 결과가 동일한 성질이다.
retryPolicy
service config(클라이언트 동작을 정의하는 JSON 설정)에 retryPolicy를 지정하면 gRPC 라이브러리가 재시도를 대신 처리한다. 재시도 기능은 기본적으로 활성화되어 있으나 기본 정책이 없으므로, 정책을 지정해야 동작한다.
import json
import grpc
service_config = json.dumps({
"methodConfig": [{
# 이 서비스의 모든 메서드에 적용한다
"name": [{"service": "device.v1.StatusService"}],
"retryPolicy": {
"maxAttempts": 4,
"initialBackoff": "0.1s",
"maxBackoff": "1s",
"backoffMultiplier": 2,
"retryableStatusCodes": ["UNAVAILABLE"],
},
}]
})
channel = grpc.insecure_channel(
"localhost:50051", options=[("grpc.service_config", service_config)]
)
maxAttempts: 첫 시도를 포함한 시도 횟수이다. 5보다 큰 값은 5로 처리한다.initialBackoff,maxBackoff,backoffMultiplier: 대기 시간의 초깃값, 상한, 증가 배수이다.retryableStatusCodes: 재시도 대상 코드이다. 비워 둘 수 없다.
재시도 중단 조건
- 응답 헤더를 수신한 뒤에는 재시도하지 않는다. 스트리밍 도중에 호출이 단절되면 애플리케이션이 다시 호출한다.
- deadline은 시도마다 새로 지정되지 않으며, 모든 시도에 하나의 deadline이 적용된다.
UNAVAILABLE이라도 멱등하지 않은 호출은 두 번 처리될 수 있다.