"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > थ्रॉटलिंग की व्याख्या: एपीआई अनुरोध सीमाओं को प्रबंधित करने के लिए एक गाइड

थ्रॉटलिंग की व्याख्या: एपीआई अनुरोध सीमाओं को प्रबंधित करने के लिए एक गाइड

2024-12-22 को प्रकाशित
ब्राउज़ करें:734

आपको अपने कोड में थ्रॉटलिंग कब लागू करनी चाहिए?

बड़ी परियोजनाओं के लिए, आमतौर पर क्लाउडफ़ेयर रेट लिमिटिंग या HAProxy जैसे टूल का उपयोग करना सबसे अच्छा होता है। ये शक्तिशाली, विश्वसनीय हैं और आपके लिए भारी सामान उठाने का ख्याल रखते हैं।

लेकिन छोटी परियोजनाओं के लिए - या यदि आप सीखना चाहते हैं कि चीजें कैसे काम करती हैं - तो आप सीधे अपने कोड में अपना स्वयं का रेट लिमिटर बना सकते हैं। क्यों?

  • यह सरल है: आप कुछ ऐसा सीधा निर्माण करेंगे जो समझने में आसान हो।
  • यह बजट के अनुकूल है: आपके सर्वर को होस्ट करने के अलावा कोई अतिरिक्त लागत नहीं है।
  • यह छोटी परियोजनाओं के लिए काम करता है: जब तक यातायात कम है, यह चीजों को तेज और कुशल बनाए रखता है।
  • यह पुन: प्रयोज्य है: आप इसे नए टूल या सेवाओं को स्थापित किए बिना अन्य परियोजनाओं में कॉपी कर सकते हैं।

आप क्या सीखेंगे

इस गाइड के अंत तक, आप जानेंगे कि अपने एपीआई को अभिभूत होने से बचाने के लिए टाइपस्क्रिप्ट में एक बुनियादी थ्रॉटलर कैसे बनाया जाए। यहां हम क्या कवर करेंगे:

  • कॉन्फ़िगर करने योग्य समय सीमाएं: प्रत्येक अवरुद्ध प्रयास दुरुपयोग को रोकने के लिए लॉकआउट अवधि को बढ़ाता है।
  • अनुरोध कैप्स: अनुमत अनुरोधों की अधिकतम संख्या निर्धारित करें। यह उन एपीआई के लिए विशेष रूप से उपयोगी है जिनमें ओपनएआई जैसी सशुल्क सेवाएं शामिल हैं।
  • इन-मेमोरी स्टोरेज: एक सरल समाधान जो रेडिस जैसे बाहरी टूल के बिना काम करता है—छोटी परियोजनाओं या प्रोटोटाइप के लिए आदर्श।
  • प्रति-उपयोगकर्ता सीमाएं: उनके आईपीवी4 पते का उपयोग करके प्रति-उपयोगकर्ता आधार पर अनुरोधों को ट्रैक करें। हम इसकी अंतर्निहित विधि से क्लाइंट आईपी को आसानी से पुनर्प्राप्त करने के लिए SvelteKit का लाभ उठाएंगे।

यह मार्गदर्शिका एक व्यावहारिक शुरुआती बिंदु के रूप में डिज़ाइन की गई है, जो उन डेवलपर्स के लिए बिल्कुल सही है जो अनावश्यक जटिलता के बिना मूल बातें सीखना चाहते हैं। लेकिन यह उत्पादन के लिए तैयार नहीं है

शुरू करने से पहले, मैं लूसिया के दर सीमित अनुभाग को सही श्रेय देना चाहता हूं।


थ्रॉटलर कार्यान्वयन

आइए थ्रॉटलर वर्ग को परिभाषित करें:

export class Throttler {
    private storage = new Map();

    constructor(private timeoutSeconds: number[]) {}
}

थ्रॉटलर कंस्ट्रक्टर टाइमआउट अवधि (टाइमआउटसेकंड) की एक सूची स्वीकार करता है। हर बार जब किसी उपयोगकर्ता को ब्लॉक किया जाता है, तो इस सूची के आधार पर अवधि उत्तरोत्तर बढ़ती जाती है। अंततः, जब अंतिम समय समाप्त हो जाता है, तो आप उपयोगकर्ता के आईपी पर स्थायी रूप से प्रतिबंध लगाने के लिए कॉलबैक भी ट्रिगर कर सकते हैं - हालांकि यह इस गाइड के दायरे से परे है।

यहां थ्रॉटलर इंस्टेंस बनाने का एक उदाहरण दिया गया है जो उपयोगकर्ताओं को अंतराल बढ़ाने से रोकता है:

const throttler = new Throttler([1, 2, 4, 8, 16]);

यह इंस्टेंस उपयोगकर्ताओं को पहली बार एक सेकंड के लिए ब्लॉक कर देगा। दो के लिए दूसरी बार, इत्यादि।

हम आईपी पते और उनके संबंधित डेटा को संग्रहीत करने के लिए एक मानचित्र का उपयोग करते हैं। एक मानचित्र आदर्श है क्योंकि यह बार-बार जोड़ने और हटाने को कुशलतापूर्वक संभालता है।

प्रो टिप: गतिशील डेटा के लिए मानचित्र का उपयोग करें जो बार-बार बदलता है। स्थिर, अपरिवर्तित डेटा के लिए, एक ऑब्जेक्ट बेहतर है। (खरगोश का बिल 1)


जब आपका एंडपॉइंट एक अनुरोध प्राप्त करता है, तो यह उपयोगकर्ता का आईपी पता निकालता है और यह निर्धारित करने के लिए थ्रॉटलर से परामर्श करता है कि अनुरोध की अनुमति दी जानी चाहिए या नहीं।

यह काम किस प्रकार करता है

  • केस ए: नया या निष्क्रिय उपयोगकर्ता

    यदि थ्रॉटलर में आईपी नहीं मिलता है, तो यह या तो उपयोगकर्ता का पहला अनुरोध है या वे काफी समय से निष्क्रिय हैं। इस मामले में:

    • कार्रवाई की अनुमति दें।
    • प्रारंभिक टाइमआउट के साथ उपयोगकर्ता का आईपी संग्रहीत करके उसे ट्रैक करें।
  • केस बी: सक्रिय उपयोगकर्ता

    यदि आईपी पाया जाता है, तो इसका मतलब है कि उपयोगकर्ता ने पिछले अनुरोध किए हैं। यहाँ:

    • जांचें कि क्या आवश्यक प्रतीक्षा समय (टाइमआउटसेकंड सरणी के आधार पर) उनके अंतिम ब्लॉक के बाद बीत चुका है।
    • यदि पर्याप्त समय बीत चुका है:
    • टाइमस्टैम्प अपडेट करें।
    • टाइमआउट इंडेक्स बढ़ाएं (ओवरफ़्लो को रोकने के लिए अंतिम इंडेक्स तक सीमित करें)।
    • यदि नहीं, तो अनुरोध अस्वीकार करें।

इस बाद वाले मामले में, हमें यह जांचने की ज़रूरत है कि क्या पिछले ब्लॉक के बाद पर्याप्त समय बीत चुका है। हम जानते हैं कि हमें किस टाइमआउटसेकंड को किसी इंडेक्स के लिए धन्यवाद देना चाहिए। यदि नहीं, तो बस वापस लौटें। अन्यथा टाइमस्टैम्प अपडेट करें।

export class Throttler {
    // ...

    public consume(key: string): boolean {
        const counter = this.storage.get(key) ?? null;
        const now = Date.now();

        // Case A
        if (counter === null) {
            // At next request, will be found.
            // The index 0 of [1, 2, 4, 8, 16] returns 1.
            // That's the amount of seconds it will have to wait.
            this.storage.set(key, {
                index: 0,
                updatedAt: now
            });
            return true; // allowed
        }

        // Case B
        const timeoutMs = this.timeoutSeconds[counter.index] * 1000;
        const allowed = now - counter.updatedAt >= timeoutMs;
        if (!allowed) {
            return false; // denied
        }

        // Allow the call, but increment timeout for following requests.
        counter.updatedAt = now;
        counter.index = Math.min(counter.index   1, this.timeoutSeconds.length - 1);
        this.storage.set(key, counter);

        return true; // allowed
    }
}

इंडेक्स को अपडेट करते समय, यह टाइमआउटसेकंड के अंतिम इंडेक्स तक सीमित हो जाता है। इसके बिना, काउंटर.इंडेक्स 1 इसे ओवरफ़्लो कर देगा और इसके बाद this.timeoutSeconds[counter.index] एक्सेस के परिणामस्वरूप रनटाइम त्रुटि होगी।

समापन बिंदु उदाहरण

यह उदाहरण दिखाता है कि थ्रॉटलर का उपयोग यह सीमित करने के लिए कैसे किया जाए कि कोई उपयोगकर्ता आपके एपीआई को कितनी बार कॉल कर सकता है। यदि उपयोगकर्ता बहुत अधिक अनुरोध करता है, तो उन्हें मुख्य तर्क चलाने के बजाय एक त्रुटि मिलेगी।

const throttler = new Throttler([1, 2, 4, 8, 16, 30, 60, 300]);

export async function GET({ getClientAddress }) {
    const IP = getClientAddress();

    if (!throttler.consume(IP)) {
        throw error(429, { message: 'Too Many Requests' });
    }

    // Read from DB, call OpenAI - do the thing.

    return new Response(null, { status: 200 });
}

Throttling Explained: A Guide to Managing API Request Limits

प्रमाणीकरण के लिए नोट

लॉगिन सिस्टम के साथ दर सीमित करने का उपयोग करते समय, आपको इस समस्या का सामना करना पड़ सकता है:

  1. एक उपयोगकर्ता लॉग इन करता है, जिससे थ्रॉटलर उनके आईपी के साथ एक टाइमआउट संबद्ध करने के लिए ट्रिगर होता है।
  2. उपयोगकर्ता लॉग आउट हो जाता है या उनका सत्र समाप्त हो जाता है (उदाहरण के लिए, तुरंत लॉग आउट हो जाता है, सत्र के साथ कुकी समाप्त हो जाती है और ब्राउज़र क्रैश हो जाता है, आदि)।
  3. जब वे शीघ्र ही दोबारा लॉग इन करने का प्रयास करते हैं, तब भी थ्रॉटलर उन्हें ब्लॉक कर सकता है, और 429 बहुत अधिक अनुरोध त्रुटि लौटाता है।

इसे रोकने के लिए, दर सीमित करने के लिए उपयोगकर्ता के आईपी के बजाय उसकी विशिष्ट उपयोगकर्ता आईडी का उपयोग करें। साथ ही, आपको अनावश्यक अवरोधों से बचने के लिए सफल लॉगिन के बाद थ्रॉटलर स्थिति को रीसेट करना होगा।

थ्रॉटलर क्लास में एक रीसेट विधि जोड़ें:

export class Throttler {
    // ...

    public reset(key: string): void {
        this.storage.delete(key);
    }
}

और सफल लॉगिन के बाद इसका उपयोग करें:

const user = db.get(email);

if (!throttler.consume(user.ID)) {
    throw error(429);
}

const validPassword = verifyPassword(user.password, providedPassword);
if (!validPassword) {
    throw error(401);
}

throttler.reset(user.id); // Clear throttling for the user

समय-समय पर सफाई के साथ पुराने आईपी रिकॉर्ड्स का प्रबंधन करना

चूंकि आपका थ्रॉटलर आईपी और दर सीमा को ट्रैक करता है, इसलिए यह सोचना महत्वपूर्ण है कि आईपी रिकॉर्ड को कैसे और कब हटाया जाए जिनकी अब आवश्यकता नहीं है। सफाई तंत्र के बिना, आपका थ्रॉटलर मेमोरी में रिकॉर्ड संग्रहीत करना जारी रखेगा, जिससे समय के साथ डेटा बढ़ने पर संभावित रूप से प्रदर्शन संबंधी समस्याएं पैदा हो सकती हैं।

इसे रोकने के लिए, आप एक क्लीनअप फ़ंक्शन लागू कर सकते हैं जो निष्क्रियता की एक निश्चित अवधि के बाद समय-समय पर पुराने रिकॉर्ड हटा देता है। थ्रॉटलर से पुरानी प्रविष्टियों को हटाने के लिए एक सरल सफाई विधि जोड़ने का एक उदाहरण यहां दिया गया है।

export class Throttler {
    // ...

    public cleanup(): void {
        const now = Date.now()

        // Capture the keys first to avoid issues during iteration (we use .delete)
        const keys = Array.from(this.storage.keys())

        for (const key of keys) {
            const counter = this.storage.get(key)
            if (!counter) {
                // Skip if the counter is already deleted (handles concurrency issues)
                return
            }

            // If the IP is at the first timeout, remove it from storage
            if (counter.index == 0) {
                this.storage.delete(key)
                continue
            }

            // Otherwise, reduce the timeout index and update the timestamp
            counter.index -= 1
            counter.updatedAt = now
            this.storage.set(key, counter)
        }
    }
}

सफाई को शेड्यूल करने का एक बहुत ही सरल तरीका (लेकिन शायद सबसे अच्छा नहीं) सेटइंटरवल के साथ है:

const throttler = new Throttler([1, 2, 4, 8, 16, 30, 60, 300])
const oneMinute = 60_000
setInterval(() => throttler.cleanup(), oneMinute)

यह सफाई तंत्र यह सुनिश्चित करने में मदद करता है कि आपका थ्रॉटलर आपके एप्लिकेशन को कुशल रखते हुए, पुराने रिकॉर्ड को अनिश्चित काल तक नहीं रखता है। हालांकि यह दृष्टिकोण सरल और कार्यान्वयन में आसान है, अधिक जटिल उपयोग के मामलों के लिए इसे और अधिक परिष्कृत करने की आवश्यकता हो सकती है (उदाहरण के लिए, अधिक उन्नत शेड्यूलिंग का उपयोग करना या उच्च संगामिति को संभालना)।

समय-समय पर सफाई के साथ, आप मेमोरी ब्लोट को रोकते हैं और सुनिश्चित करते हैं कि जिन उपयोगकर्ताओं ने कुछ समय में अनुरोध करने का प्रयास नहीं किया है, उन्हें अब ट्रैक नहीं किया जाता है - यह आपकी दर-सीमित प्रणाली को स्केलेबल और संसाधन-कुशल दोनों बनाने की दिशा में पहला कदम है।


  1. यदि आप साहसी महसूस कर रहे हैं, तो आपको यह पढ़ने में रुचि हो सकती है कि संपत्तियों का आवंटन कैसे किया जाता है और यह कैसे बदलता है। इसके अलावा, इनलाइन कैश जैसे वीएम अनुकूलन के बारे में क्यों नहीं, जो विशेष रूप से मोनोमोर्फिज्म द्वारा पसंद किया जाता है। आनंद लेना। ↩

विज्ञप्ति वक्तव्य यह आलेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/didof/throttting-explained-a-guide-to-maneasing-api-request-limits-102a?1 यदि कोई उल्लंघन है, तो कृपया स्टडी_गोलंग@163.com पर संपर्क करें। इसे हटाने के लिए
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3