지수 백오프로 작업을 재시도하는 golang 라이브러리

8754 단어 showdevprogramminggo
다른 타이밍 알고리즘을 사용하여 작업을 재시도하기 위한 작은 라이브러리인 go-again 를 만들었습니다. 기본적으로 지터와 함께 지수 백오프를 사용하여 재시도할 때마다 다양한 지연을 생성합니다.


jdvr / 다시 가다


반복해서 작업을 재시도하는 일련의 유틸리티 알고리즘입니다.





다시 가다



지수 백오프 및 즉시 사용 가능한 지속적인 지연 지원 기능을 갖춘 간단하고 구성 가능한 이동용 재시도 라이브러리
backoff에서 영감을 받음 .

특징


  • 구성 가능한 지연 계산 알고리즘
  • 즉시 사용 가능한 지수 백오프 및 지속적인 지연 지원
  • 제네릭 지원
  • 간단하고 깔끔한 인터페이스

  • 두 가지 주요 개념이 있습니다.


  • 재시도: 작업이 주어지면 틱 계산기가 영구 오류 또는 시간 초과가 발생할 때까지 계속 재시도합니다
  • .
  • TicksCalculator: 재시도 사이에 재시도 대기 시간을 제공합니다
  • .

    예:


    지수 백오프를 사용하여 API 호출


    package main
    import (
        "context"
        "errors"
        "fmt"
        "net/http"
    
        "github.com/jdvr/go-again"
    )
    
    
    func main() {
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()
    
        apiResponse, err := again.Retry[*http.Response](ctx, func(ctx context.Context) (*http.Response, error) {
            fmt.Println("Running Operation"

    Retry any function using exponential backoff:

    package main
    
    import (
        "context"
        "errors"
        "fmt"
        "net/http"
    
        "github.com/jdvr/go-again"
    )
    
    
    func main() {
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()
    
        apiResponse, err := again.Retry[*http.Response](ctx, func(ctx context.Context) (*http.Response, error) {
            fmt.Println("Running Operation")
    
            resp, err := http.DefaultClient.Get("https://sameflaky.api/path")
            if err != nil {
                // operation will be retried
                return nil, err
            }
    
            if resp.StatusCode == http.StatusForbidden {
                // no more retries
                return nil, again.NewPermanentError(errors.New("no retry, permanent error"))
            }
    
            if resp.StatusCode > 400 {
                return nil, errors.New("this will be retry")
            }
    
            // do whatever you need with a valid response ...
    
            return resp, nil // no retry
        })
        if err != nil {
            panic(err)
        }
    
        fmt.Printf("Finished with response %v\n", apiResponse)
    }
    


    지수 백오프 및 지터



    지수 백오프에 대한 인용Wikpedia:

    Exponential backoff is an algorithm that uses feedback to multiplicatively decrease the rate of some process to gradually find an acceptable rate.



    아이디어는 문제가 단지 시간 문제이기 때문에 시스템이 어느 시점에서 작동할 것이라고 가정하고 각 재시도 사이에 더 긴 대기 시간을 생성하는 것입니다.

    실패할 수 있는 사용자 프로필을 가져오는 API가 있다고 가정합니다. 이 경우 재시도 기능을 도입하여 요청을 계속 시도할 수 있으며 이 재시도는 각 기간 사이에 더 오래 대기합니다. 이제 워크로드로 인해 API가 충돌했다고 상상해 보십시오.

    백오프는 도움이 되지 않습니다. 요청이 지연 기간으로 트리거되지만 모든 클라이언트는 동일한 지연으로 동일한 알고리즘을 따르므로 워크로드 문제는 더욱 악화됩니다.

    이 알고리즘은 지터를 사용하여 서로 다른 클라이언트 간에 작은 임의 지연 간격을 생성하여 정확한 지연 문제를 해결합니다. 모든 클라이언트가 500ms를 기다리게 하는 대신 450에서 550 사이의 임의의 숫자를 선택하여 서버 작업 부하를 현명하게 분산합니다.

    다시 가다



    재미로 이 라이브러리를 만들었지만 프로덕션 준비가 되어 있으며 물론 기회가 되는 대로 사용할 것입니다. 지금 사용하고 있는 라이브러리인 backoff 에서 영감을 받았습니다.
    go-again는 지수 백오프를 넘어 간단하게 유지하려는 경우를 대비하여 a constant delay에 대한 또 다른 알고리즘을 제공합니다. 또한 your own algorithm easily by implementing an interface 을 정의할 수 있습니다.

    좋은 웹페이지 즐겨찾기