본문 바로가기
WIKI 기술 지식 베이스

재시도와 타임아웃

원문 보기 위키 갱신

재시도와 타임아웃 (Retries and Timeouts)

타임아웃과 자동 재시도는 서비스 메시가 부분적이거나 일시적인 애플리케이션 장애를 우아하게 처리하기 위해 가진 가장 강력한 메커니즘 중 둘입니다. 이 문서에서는 주석(annotation)과 헤더를 이용해 Linkerd의 재시도와 타임아웃을 설정하는 방법을 설명해요.

출처: Linkerd Retries and Timeouts

본문

타임아웃과 자동 재시도는 서비스 메시가 부분적이거나 일시적인 애플리케이션 장애를 우아하게 처리할 수 있게 해주는 가장 강력한 메커니즘 중 두 가지입니다.

  • 타임아웃을 이용하면 Linkerd가 시간 제한을 초과하는 요청을 취소할 수 있습니다.
  • 재시도를 이용하면 Linkerd가 실패한 요청을 자동으로 재시도하고, 경우에 따라 다른 엔드포인트로 보낼 수 있습니다.

타임아웃과 재시도는 retry.linkerd.io/http, timeout.linkerd.io/request 같은 일련의 주석으로 설정합니다. 이런 주석은 HTTPRoute나 GRPCRoute 리소스에 배치해 해당 리소스와 일치하는 HTTP 또는 gRPC 요청의 동작을 구성합니다. 또는 Service 리소스에 배치해 해당 서비스로 가는 모든 트래픽에 대한 재시도와 타임아웃을 구성할 수도 있어요.

Linkerd 2.16부터 타임아웃과 재시도는 조합됩니다. 즉 타임아웃이 발생한 요청도 재시도 후보가 될 수 있습니다.

Note

재시도와 타임아웃은 아웃바운드(클라이언트) 쪽에서 수행됩니다. 즉 주석을 어디에 배치하든 트래픽의 출발지가 메시에 포함되어 있어야 합니다.

Note

재시도와 타임아웃은 headless 서비스에서는 동작하지 않습니다. Linkerd가 대상 IP 주소를 기준으로 서비스 디스커버리 정보를 읽기 때문인데, 그 IP가 pod IP라면 pod가 어느 서비스에 속하는지 알 수 없기 때문입니다.

Warning

Linkerd 2.16 이전에는 재시도와 타임아웃을 ServiceProfile로 구성했습니다. 서비스 프로필은 여전히 지원되지만, HTTPRoute나 GRPCRoute로 구성한 재시도는 ServiceProfile과 호환되지 않습니다. 어떤 Service에 ServiceProfile이 정의되어 있으면 프록시는 ServiceProfile의 재시도 구성을 사용하고, 재시도 주석은 무시합니다.

재시도를 안전하게 사용하기

재시도는 옵트인(opt-in) 동작이라 어느 정도 생각과 계획이 필요합니다. 잘못 사용하면 위험할 수 있어요. 먼저, 호출될 때마다 시스템 상태를 바꾸는 요청을 자동으로 재시도하면 재앙이 될 수 있습니다. 그래서 재시도는 멱등(idempotent) 메서드, 즉 여러 번 호출해도 같은 효과가 나는 메서드에만 사용해야 합니다.

둘째, 재시도는 정의상 시스템에 부하를 증가시킵니다. 요청이 계속 재시도되는 서비스 집합은 회복할 시간을 갖지 못한 채 재시도 때문에 다운될 수도 있습니다.

전체 신뢰성을 개선하면서 위험을 크게 키우지 않는 재시도 동작의 정확한 구성은 사용자의 세심한 판단이 필요합니다.

요청별 정책 (Per-request policies)

위에서 설명한 주석 방식 외에도, 특정 HTTP 헤더를 설정해 요청 단위로 재시도와 타임아웃을 정할 수 있습니다.

이 요청별 정책을 활성화하려면 Linkerd를 --set policyController.additionalArgs="--allow-l5d-request-headers" 플래그나 이에 해당하는 Helm 값으로 설치해야 합니다.

Warning

애플리케이션이 신뢰할 수 없는 출처의 필터링되지 않은 요청을 받는다면 요청별 정책을 활성화하면 안 됩니다. 예를 들어 필터링되지 않은 인터넷 트래픽을 받는 인그레스 컨트롤러를 메시화했는데(skip-inbound-ports로 Linkerd가 pod로 들어오는 인바운드 트래픽을 처리하지 않도록 지시하지 않았다면), 신뢰할 수 없는 클라이언트가 자기 요청에 Linkerd 재시도·타임아웃 정책을 지정할 수 있게 됩니다.

요청별 정책을 활성화하면 다음 헤더를 설정해 개별 요청에 타임아웃·재시도 정책을 적용할 수 있어요.

  • l5d-retry-http: retry.linkerd.io/http 주석을 덮어씁니다
  • l5d-retry-grpc: retry.linkerd.io/grpc 주석을 덮어씁니다
  • l5d-retry-limit: retry.linkerd.io/limit 주석을 덮어씁니다
  • l5d-retry-timeout: retry.linkerd.io/timeout 주석을 덮어씁니다
  • l5d-timeout: timeout.linkerd.io/request 주석을 덮어씁니다
  • l5d-response-timeout: timeout.linkerd.io/response 주석을 덮어씁니다

더 알아보기 (Learn more)

  • 재시도 레퍼런스
  • 타임아웃 레퍼런스
  • 라우트별 메트릭으로 HTTP 애플리케이션 디버깅하기에는 재시도·타임아웃 주석의 예시가 들어 있습니다.