Go를 사용하여 Exponential Backof And Jitter 설치

15546 단어 Gotech

Backof And Jitter 소개


이것은 요청이 실패했을 때 다시 시도하는 간격을 조정하는 알고리즘이다
재시도 시간을 엇갈리게 함으로써 요청의 성공률을 높인다.

Exponential Backoff


Exponential Backoff는 지수에서 재시도 간격을 늘리면서 재시도하는 방법입니다.
  • 첫 번째 요청 실패: 1초 대기 후 재시도
  • 2차 요청 실패: 2초 대기 후 재시도
  • 3차 요청 실패: 4초 후 재시도
  • 이렇게 대기 시간을 늘려줍니다.

    Jitter


    Exponential Backoff는 일정한 간격으로 재시도를 진행하기 때문에 많은 요청에서 재시도가 발생하는 경우 재시도의 실행 시간은 같은 문제가 된다.
    따라서 Jitter라고 불리는 임의 값을 적용함으로써 재시도 시기를 분산시킬 수 있다.
    Exponential Backof And Jitter에 대한 자세한 내용은 아래 블로그를 참조하십시오.
    https://aws.typepad.com/sajp/2015/03/backoff.html
    이번에 우리는 Go 언어로 이 블로그에서 소개한 Jiter3 모델을 각각 실시하였다.

    설치 예


    Exponential Backoff And Full Jitter


    sleep = random_between(0 min(cap, base * 2 ** attempt))
    
    ※ 식의 인용원: Exponential Backoff And Jitter

    이루어지다


    main.go
    package main
    
    import (
    	"fmt"
    	"math"
    	"math/rand"
    	"time"
    )
    
    const base int = 1000
    const cap int = 10000
    
    func main() {
    	rand.Seed(time.Now().UnixNano())
    	for i := 0; i < 5; i++ {
    		Sleep(i)
    	}
    }
    
    func Sleep(retryCount int) {
    	temp := base * int(math.Pow(2, float64(retryCount)))
    	if temp > cap {
    		temp = cap
    	}
    
    	sleep := rand.Intn(temp)
    	fmt.Printf("sleep: %d ms\n", sleep)
    	time.Sleep(time.Duration(sleep) * time.Millisecond)
    }
    

    실행 결과


    $ go run main.go
    sleep: 692 ms
    sleep: 259 ms
    sleep: 1846 ms
    sleep: 7535 ms
    sleep: 673 ms
    

    Exponential Backoff And Equal Jitter


    temp = min(cap, base * 2 ** attempt)
    sleep = temp / 2 + random_between(0, temp / 2)
    
    ※ 식의 인용원: Exponential Backoff And Jitter

    이루어지다


    main.go
    package main
    
    import (
    	"fmt"
    	"math"
    	"math/rand"
    	"time"
    )
    
    const base int = 1000
    const cap int = 10000
    
    func main() {
    	rand.Seed(time.Now().UnixNano())
    	for i := 0; i < 5; i++ {
    		Sleep(i)
    	}
    }
    
    func Sleep(retryCount int) {
    	temp := base * int(math.Pow(2, float64(retryCount)))
    	if temp > cap {
    		temp = cap
    	}
    
    	sleep := temp/2 + rand.Intn(temp/2)
    	fmt.Printf("sleep: %d ms\n", sleep)
    	time.Sleep(time.Duration(sleep) * time.Millisecond)
    }
    

    실행 결과


    $ go run main.go
    sleep: 817 ms
    sleep: 1889 ms
    sleep: 3260 ms
    sleep: 5198 ms
    sleep: 9337 ms
    

    Exponential Backoff And Decorrlated Jitter


    sleep = min(cap, random_between(base, sleep * 3))
    
    ※ 식의 인용원: Exponential Backoff And Jitter

    이루어지다


    main.go
    package main
    
    import (
    	"fmt"
    	"math/rand"
    	"time"
    )
    
    const base int = 1000
    const cap int = 10000
    
    func main() {
    	rand.Seed(time.Now().UnixNano())
    	prevSleep := base
    	for i := 0; i < 5; i++ {
    		prevSleep = Sleep(prevSleep, i)
    	}
    }
    
    func Sleep(prevSleep int, retryCount int) int {
    	sleep := rand.Intn((prevSleep*3)-base+1) + base
    	if sleep > cap {
    		sleep = cap
    	}
    
    	fmt.Printf("sleep: %d ms\n", sleep)
    	time.Sleep(time.Duration(sleep) * time.Millisecond)
    	return sleep
    }
    

    실행 결과


    $ go run main.go
    sleep: 2218 ms
    sleep: 2060 ms
    sleep: 1845 ms
    sleep: 4990 ms
    sleep: 10000 ms
    

    끝맺다


    클라이언트와 서버의 부하를 줄이기 위해 적당한 재시도!

    좋은 웹페이지 즐겨찾기