맡고 있는 프로젝트에서 다른 서버와 통신을 하는 코드를 보던 중,
통신을 하는 서버에서 동시성 이슈로 재시도를 원하는 에러코드가 내려왔고, 이에 잠깐의 sleep을 한 후에 재시도하는 것을 볼 수 있었다.
Retry?
MSA구조에서는 서로 다른 서버와 통신을 할 일이 많다.
그렇기 때문에 서로 다른 서버와 통신할 때 실패율을 줄이는 것이 중요하며, 호출 재시도를 하며 실패율을 줄일 수 있다.
보통 Sleep을 해주는 이유는 동시에 요청이 왔을 때, 바로 재시도를 하게 된다면 동시성 이슈에 있어서 성공률은 떨어지기 때문이다.
그래서 보통은 Exponential Backoff Algorithm ( 백오프 ) 를 사용해야하는 걸로 알고 있었다.
1번째 재시도 : 1초 -> 2번째 재시도 : 2초 -> 3번째 재시도 : 4초 -> 8초.... 16초...32초
( 재시도 횟수마다 기다리는 시간이 지수 단위로 증가 )
그러나 내가 보던 코드에서는 0.1~0.4초의 범위에 랜덤한 값을 Sleep하며 재시도를 하고 있었다.
왜,,, Exponential Backoff한 Retry가 아닌 랜덤한 값을 주고 있었던 걸까?..
그 이유가 Jitter라는 것을 동료 개발자에게 들을 수 있었다.
Jitter란?
Random한 시간으로 Retry 사이의 시간을 설정해주는 방법
sleep = radom_between(0, min(xxx))
( 참고 : https://aws.amazon.com/ko/blogs/architecture/exponential-backoff-and-jitter/ )
위 글을 참고하면,
Exponential Backoff를 사용해서 재시도를 한다해도 만약 같은 시간에서의 첫 시도에 호출된 수가 많게 되면, 재시도하는 시간이 증가하더라도 대기하는 시간이 계속 같기 때문에 효과가 없을 수 있는 문제가 발생할 수 있다.
이러한 문제를 방지하기 위해서 같은 시간에 첫 호출이 발생해도 Random 한 값을 주어 해결할 수 있도록 하면, 위 글의 그래프에서 볼 수 있 듯이 높은 효율성과 낮은 Competing Clients를 얻을 수 있다.
궁금하신 것이 있으시면 언제든지 댓글 달아주세요!
'F.Y.R' 카테고리의 다른 글
[Error] org.hibernate.LazyInitializationException: could not initialize proxy (0) | 2021.12.12 |
---|---|
[Error] Cause: java.lang.ExceptionInInitializerError (0) | 2021.10.30 |