حسنًا يا رفاق، لقد تناولنا الكثير حتى الآن: مصادقة JWT، واتصالات قاعدة البيانات، والتسجيل، ومعالجة الأخطاء. ولكن ماذا يحدث عندما تبدأ واجهة برمجة التطبيقات (API) الخاصة بك في التعرض لانتقادات شديدة من الطلبات؟ وبدون التحكم، يمكن أن تؤدي حركة المرور العالية إلى بطء أوقات الاستجابة أو حتى التوقف عن العمل. ?
سنقوم بحل هذه المشكلة هذا الأسبوع من خلال تطبيق تحديد المعدل للتحكم في تدفق حركة المرور. سنستخدم حزمة golang.org/x/time/rate البسيطة والفعالة. لاحقًا، عندما يصبح حل ThrottleX الخاص بي جاهزًا، سأوضح لك كيفية دمج ذلك كخيار أكثر قابلية للتطوير. (ملاحظة، راجع GitHub الخاص بي على github.com/neelp03/throttlex للحصول على التحديثات! لا تتردد في التعليق على أي مشكلات تراها هناك o7)
يشبه تحديد السعر الحارس لواجهة برمجة التطبيقات (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) بحيث يجب أن يمر كل طلب من خلالها:
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
الآن، دعنا نصل إلى واجهة برمجة التطبيقات ببعض الطلبات. يمكنك استخدام حلقة مع الضفيرة لمحاكاة طلبات متعددة على التوالي:
for i in {1..10}; do curl http://localhost:8000/books; done
نظرًا لأننا قمنا بتعيين الحد الأقصى على 5 طلبات في الدقيقة، فمن المفترض أن تشاهد استجابات 429 طلبًا كبيرًا بمجرد تجاوز المعدل المسموح به.
وها هو الأمر - تحديد المعدل باستخدام golang.org/x/time/rate للحفاظ على استقرار واجهة برمجة التطبيقات لديك واستجابة تحت الضغط. يعد تحديد المعدل أداة بالغة الأهمية لأي واجهة برمجة تطبيقات قابلة للتطوير، ونحن هنا مجرد نقطة الصفر.
بمجرد أن يصبح ThrottleX جاهزًا للإنتاج، سأقوم بنشر برنامج تعليمي للمتابعة لتوضيح كيفية دمجه في Go API الخاص بك لمزيد من المرونة وتحديد المعدل الموزع. راقب مستودع ThrottleX GitHub الخاص بي للحصول على التحديثات!
في الأسبوع المقبل، سنقوم بوضع واجهة برمجة التطبيقات الخاصة بنا في حاوية مع Docker، لذا فهي جاهزة للتشغيل في أي مكان. ترقبوا، وترميز سعيد! ??
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3