"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > Go API에 API 속도 제한 추가

Go API에 API 속도 제한 추가

2024-11-08에 게시됨
검색:242

Adding API Rate Limiting to Your Go API

자, 여러분, 지금까지 JWT 인증, 데이터베이스 연결, 로깅, 오류 처리 등 많은 내용을 다루었습니다. 하지만 API에 요청이 너무 많이 들어오기 시작하면 어떻게 될까요? 제어가 없으면 트래픽이 많아 응답 시간이 느려지거나 가동 중지 시간이 발생할 수 있습니다. ?

이번 주에는 트래픽 흐름을 제어하기 위해 속도 제한을 구현하여 이 문제를 해결해 보겠습니다. 우리는 간단하고 효과적인 golang.org/x/time/rate 패키지를 사용할 것입니다. 나중에 내 ThrottleX 솔루션이 준비되면 이를 보다 확장 가능한 옵션으로 통합하는 방법을 보여 드리겠습니다. (잠깐만, 업데이트는 github.com/neelp03/throttlex에서 내 GitHub를 확인하세요! 거기에서 발견되는 문제가 있으면 언제든지 의견을 보내주세요. o7)

왜 속도 제한을 하는가? ?

속도 제한은 API의 경비원과 같습니다. 특정 기간 내에 사용자가 보낼 수 있는 요청 수를 제어합니다. 이렇게 하면 API가 압도되는 것을 방지하여 모든 사용자에게 원활하고 공정한 액세스를 보장합니다. 속도 제한은 다음의 경우에 필수적입니다.

  • 남용 방지: 악의적인 행위자나 지나치게 열성적인 사용자가 API를 압도하는 것을 방지합니다.
  • 안정성: 트래픽 급증 중에도 API의 응답성과 안정성을 유지합니다.
  • 공정성: 리소스를 사용자 간에 균등하게 공유할 수 있습니다.

1단계: 시간/요금 패키지 설치

golang.org/x/time/rate 패키지는 확장된 Go 라이브러리의 일부이며 간단한 토큰 기반 속도 제한기를 제공합니다. 시작하려면 다음을 설치해야 합니다.


go get golang.org/x/time/rate


2단계: 속도 제한기 설정

클라이언트가 만들 수 있는 요청 수를 제어하는 ​​속도 제한 미들웨어를 만들어 보겠습니다. 이 예에서는 클라이언트를 분당 5개 요청으로 제한합니다.


package main

import (
    "net/http"
    "golang.org/x/time/rate"
    "sync"
    "time"
)

// Create a struct to hold each client's rate limiter
type Client struct {
    limiter *rate.Limiter
}

// In-memory storage for clients
var clients = make(map[string]*Client)
var mu sync.Mutex

// Get a client's rate limiter or create one if it doesn't exist
func getClientLimiter(ip string) *rate.Limiter {
    mu.Lock()
    defer mu.Unlock()

    // If the client already exists, return the existing limiter
    if client, exists := clients[ip]; exists {
        return client.limiter
    }

    // Create a new limiter with 5 requests per minute
    limiter := rate.NewLimiter(5, 1)
    clients[ip] = &Client{limiter: limiter}
    return limiter
}


3단계: 속도 제한 미들웨어 생성

이제 속도 제한에 따라 액세스를 제한하는 미들웨어에서 getClientLimiter 함수를 사용해 보겠습니다.


func rateLimitingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ip := r.RemoteAddr
        limiter := getClientLimiter(ip)

        // Check if the request is allowed
        if !limiter.Allow() {
            http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
            return
        }

        next.ServeHTTP(w, r)
    })
}


작동 방식:

  1. IP 기반 제한: 각 클라이언트는 IP 주소로 식별됩니다. 클라이언트의 IP를 확인하고 속도 제한기를 할당합니다.
  2. 요청 확인:limiter.Allow() 메서드는 클라이언트가 속도 제한 내에 있는지 확인합니다. 그렇다면 요청은 다음 핸들러로 진행됩니다. 그렇지 않은 경우 429 요청이 너무 많습니다.
  3. 로 응답합니다.

4단계: 미들웨어를 전역적으로 적용합니까?

이제 모든 요청이 API를 통과하도록 속도 제한기를 API에 연결하겠습니다.


func main() {
    db = connectDB()
    defer db.Close()

    r := mux.NewRouter()

    // Apply rate-limiting middleware globally
    r.Use(rateLimitingMiddleware)

    // Other middlewares
    r.Use(loggingMiddleware)
    r.Use(errorHandlingMiddleware)

    r.HandleFunc("/login", login).Methods("POST")
    r.Handle("/books", authenticate(http.HandlerFunc(getBooks))).Methods("GET")
    r.Handle("/books", authenticate(http.HandlerFunc(createBook))).Methods("POST")

    fmt.Println("Server started on port :8000")
    log.Fatal(http.ListenAndServe(":8000", r))
}


r.Use(rateLimitingMiddleware)를 적용하여 들어오는 모든 요청이 엔드포인트에 도달하기 전에 속도 제한기에 의해 확인되도록 합니다.


5단계: 속도 제한 테스트?

서버를 시작하세요:


go run main.go


이제 몇 가지 요청으로 API를 실행해 보겠습니다. 컬이 포함된 루프를 사용하여 여러 요청을 연속적으로 시뮬레이션할 수 있습니다.


for i in {1..10}; do curl http://localhost:8000/books; done


제한을 분당 5개 요청으로 설정했으므로 허용된 속도를 초과하면 429 요청이 너무 많습니다 응답이 표시됩니다.


다음은 무엇입니까?

그리고 거기에 golang.org/x/time/rate를 통한 속도 제한 기능이 있어 API를 안정적으로 유지하고 압력이 가해지는 상황에서도 응답성을 유지할 수 있습니다. 속도 제한은 확장 가능한 API에 중요한 도구이며 여기서는 단지 표면적인 부분만 살펴보겠습니다.

ThrottleX가 프로덕션 준비가 되면 더 많은 유연성과 분산 속도 제한을 위해 Go API에 통합하는 방법을 보여주는 후속 튜토리얼을 게시하겠습니다. 내 ThrottleX GitHub 저장소에서 업데이트를 확인하세요!

다음 주에는 Docker를 사용하여 API를 컨테이너화하여 어디에서나 실행할 수 있도록 할 예정입니다. 계속 지켜봐 주시기 바랍니다. 즐거운 코딩 되세요! ??

릴리스 선언문 이 글은 https://dev.to/neelp03/adding-api-rate-limiting-to-your-go-api-3fo8?1 에서 복제되었습니다. 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다. 그것
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3