타임 아웃과 리트라이에 대해서 알아보려고 한다. 타임 아웃은 서비스가 요청에 대해 응답하지 않고 기다리는 최대 시간을 의미한다.

서비스 간의 통신에서 대기 시간이 길어져 사용자 경험이 저하되는 것을 방지하고, 시스템 자원을 적절히 관리하기 위해 필요하다.

리트라이는 실패한 요청에 대해 자동으로 다시 시도하는 기능으로 일시적인 오류로 인해 요청이 실패하는 경우, 요청을 다시 시도함으로써 성공적인 응답을 받을 수 있는 가능성을 높여준다. 구현 자체는 간단하니 하나씩 살펴보자.

 

Timeout 구현

VirtualService에서 간단하게 설정해 주면 된다. 

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtual-service
spec:
hosts:
- "test.io"
http:
- route:
- destination:
host: test
timeout: 0.5s

이렇게 설정하면 0.5초 이상 응답이 걸리게 되면 500timeout 처리가 된다. 서비스가 타이트한 응답 속도를 받기를 원한다면 이것을 타이트하게 설정해 주면 에러발생으로 쉽게 응답이 느리다는 것을 알 수 있다. 

 

Retries 구현

실패의 유형은 네트워크 실패, 리소스에 대한 실패, 응답에 대한 실패등등 다양하다. 일단 디폴트를 0으로 설정하고 stern이라는 도구로 로그를 살펴보자.

istioctl install --set profile=demo --set meshConfig.defaultHttpRetryPolicy.attempts=0
--- # 도구 설치
brew install stren
---
stern istiod- -n istio-system
..
istiod-fd9tkasfb-5j4k5 discovery "defaultHttpRetryPolicy": {
istiod-fd9tkasfb-5j4k5 discovery
istiod-fd9tkasfb-5j4k5 discovery }
..

defaultHttpRetryPolicy가 비어 있는 것을 볼 수 있다. 이제 실제로 임의로 홀수번째 요청이 실패하는 로직을 넣은 애플리케이션을 넣으면 500으로 예외가 온다. 

500
200
500
200
500
~~
500

이제 VirtualService에 retry를 추가해주자. 

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtual-service
spec:
hosts:
- "test.io"
http:
- route:
- destination:
host: test
retries:
attempts: 2

 

이렇게 하면 재시도를 통해서 모두 정상 응답이 오는 것을 볼 수 있다.

200
200
200
~
200

코드에 대한 커스터마이징도 가능하다. 예를 들어서 500뿐만아니라 503 같은 응답까지 커버하려면 아래와 같이 한다.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtual-service
spec:
hosts:
- "test.io"
http:
- route:
- destination:
host: test
retries:
attempts: 2
retryOn: 5xx