자, 여러분, 지금까지 JWT 인증, 데이터베이스 연결, 로깅, 오류 처리 등 많은 내용을 다루었습니다. 하지만 API에 요청이 너무 많이 들어오기 시작하면 어떻게 될까요? 제어가 없으면 트래픽이 많아 응답 시간이 느려지거나 가동 중지 시간이 발생할 수 있습니다. ?
이번 주에는 트래픽 흐름을 제어하기 위해 속도 제한을 구현하여 이 문제를 해결해 보겠습니다. 우리는 간단하고 효과적인 golang.org/x/time/rate 패키지를 사용할 것입니다. 나중에 내 ThrottleX 솔루션이 준비되면 이를 보다 확장 가능한 옵션으로 통합하는 방법을 보여 드리겠습니다. (잠깐만, 업데이트는 github.com/neelp03/throttlex에서 내 GitHub를 확인하세요! 거기에서 발견되는 문제가 있으면 언제든지 의견을 보내주세요. o7)
속도 제한은 API의 경비원과 같습니다. 특정 기간 내에 사용자가 보낼 수 있는 요청 수를 제어합니다. 이렇게 하면 API가 압도되는 것을 방지하여 모든 사용자에게 원활하고 공정한 액세스를 보장합니다. 속도 제한은 다음의 경우에 필수적입니다.
golang.org/x/time/rate 패키지는 확장된 Go 라이브러리의 일부이며 간단한 토큰 기반 속도 제한기를 제공합니다. 시작하려면 다음을 설치해야 합니다.
go get golang.org/x/time/rate
클라이언트가 만들 수 있는 요청 수를 제어하는 속도 제한 미들웨어를 만들어 보겠습니다. 이 예에서는 클라이언트를 분당 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 }
이제 속도 제한에 따라 액세스를 제한하는 미들웨어에서 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) }) }
이제 모든 요청이 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)를 적용하여 들어오는 모든 요청이 엔드포인트에 도달하기 전에 속도 제한기에 의해 확인되도록 합니다.
서버를 시작하세요:
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를 컨테이너화하여 어디에서나 실행할 수 있도록 할 예정입니다. 계속 지켜봐 주시기 바랍니다. 즐거운 코딩 되세요! ??
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3