」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 控制傳出速率限制

控制傳出速率限制

發佈於2024-07-30
瀏覽:104

讓我們想像這樣一個場景:有一個與第三方 API 互動的分散式應用程式。通常,第三方 API 具有速率限制控制機制,以避免其客戶端突發請求並導致服務停機。在這樣的場景下,呼叫者如何在分散式環境中控制向第三方API發出請求的速率?這篇文章討論了解決這個問題的可能策略。

有多種演算法可以控制請求速率,但這裡我們將重點放在令牌桶演算法,因為它相對容易理解和實現。該演算法規定:一個桶最多可以容納T令牌,當應用程式想要向第三方API發出請求時,它必須採取1桶中的令牌。如果桶子是空的,則必須等到桶中至少有 1 令牌。此外,桶子會以 R 令牌/​​毫秒的固定速率重新填充 1 令牌。

令牌桶演算法很容易理解,但是如何在分散式環境中使用它來控制對第三方API的傳出請求?

如果想要在分散式環境中控制傳出速率限制,則需要當前速率限制的集中事實來源。有幾種方法可以實現事實來源,我用可能的實現理想化了下圖:

Controlling outgoing rate limit

上圖中,我們有一個分佈在多個pod中的應用程序,每個pod都可以向第三方API發出請求。在應用基礎設施中,有一個TCP伺服器透過令牌桶演算法來控制速率限制。在向第三方 API 發出請求之前,pod 會向 TCP 伺服器請求新的令牌,並且 pod 會等待 TCP 伺服器的回應,直到至少有一個可用令牌。令牌可用後,Pod 會向第三方 API 發出請求。

TCP 伺服器實作可以在這個儲存庫 https://github.com/rafaquelhodev/rlimit/ 中找到,在下一節中我將簡要討論 golang 中的令牌桶實作。

令牌桶實現

下面,我將展示令牌桶實現背後的主要想法。請查看 https://github.com/rafaquelhodev/rlimit/ 儲存庫以了解詳細的實作。

速率限制控制集中在TokenBucket結構體:

type TokenBucket struct {
    id           string
    mu           sync.Mutex
    tokens       int64
    maxTokens    int64
    refillPeriod int64
    cron         chan bool
    subs         []chan bool
}

您可以注意到TokenBucket結構中有一個subs屬性。基本上,這是特定令牌桶的訂閱者陣列:每次用戶端請求令牌時,用戶端都會新增到 subs 陣列中,並且當新令牌新增到儲存桶時會通知客戶端。

啟動桶時,我們需要提供桶可以支援的最大令牌數(maxTokens)以及令牌添加到桶中的時間量(refillPeriod):

func newTokenBucket(id string, maxTokens int64, refillPeriod int64) *TokenBucket {
    bucket := &TokenBucket{
        id:           id,
        tokens:       0,
        maxTokens:    maxTokens,
        refillPeriod: refillPeriod,
        cron:         make(chan bool),
        subs:         make([]chan bool, 0),
    }
    fmt.Printf("refill period  = %d\n", refillPeriod)
    bucket.startCron()
    return bucket
}

現在,您可能想知道「如何將代幣新增至儲存桶?」。為此,當建立儲存桶時,會啟動一個 cron 作業,並在每個 refillPeriod 毫秒時,將一個新令牌新增至儲存桶:

func (tb *TokenBucket) startCron() {
    ticker := time.NewTicker(time.Duration(tb.refillPeriod) * time.Millisecond)

    go func() {
        for {
            select {
            case  0 {
                        sub := tb.subs[0]
                        tb.subs = tb.subs[1:]
                        sub 



最後,當客戶端想要從桶中取得令牌時,必須呼叫 waitAvailable 函數:

func (tb *TokenBucket) waitAvailable() bool {
    tb.mu.Lock()

    if tb.tokens > 0 {
        fmt.Printf("[CONSUMING TOKEN] - id = %s\n", tb.id)
        tb.tokens -= 1
        tb.mu.Unlock()
        return true
    }

    fmt.Printf("[WAITING TOKEN] - id %s\n", tb.id)

    ch := tb.tokenSubscribe()

    tb.mu.Unlock()

    





靈感來自 https://github.com/Mohamed-khattab/Token-bucket-rate-limiter

版本聲明 本文轉載於:https://dev.to/rafaquelhodev/controlling-outgoing-rate-limit-3klg?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    查詢模式實現缺失:解決“無法找到”錯誤在Silverlight應用程序中,嘗試使用LINQ建立LINQ連接以錯誤而實現的數據庫”,無法找到查詢模式的實現。”當省略LINQ名稱空間或查詢類型缺少IEnumerable 實現時,通常會發生此錯誤。 解決問題來驗證該類型的質量是至關重要的。在此特定實例...
    程式設計 發佈於2025-04-17
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-04-17
  • 如何避免Go語言切片時的內存洩漏?
    如何避免Go語言切片時的內存洩漏?
    ,a [j:] ...雖然通常有效,但如果使用指針,可能會導致內存洩漏。這是因為原始的備份陣列保持完整,這意味著新切片外部指針引用的任何對象仍然可能佔據內存。 copy(a [i:] 對於k,n:= len(a)-j i,len(a); k
    程式設計 發佈於2025-04-17
  • Java靜態方法導入使用時機及注意事項
    Java靜態方法導入使用時機及注意事項
    在最近的代碼評論中,建議開發人員不要使用靜態方法導入。這引發了有關此功能的適當用例的討論。 審稿人提出的一個問題是,似乎屬於當前類的無限制方法呼叫引起的潛在混亂。儘管這在某些情況下可能是一個問題,但Sun的官方Java文檔建議只有在誘導“濫用繼承”或避免聲明常數的本地副本時,建議使用靜態導入。 在...
    程式設計 發佈於2025-04-17
  • 如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    為有效的slug生成首先,該函數用指定的分隔符替換所有非字母或數字字符。此步驟可確保slug遵守URL慣例。隨後,它採用ICONV函數將文本簡化為us-ascii兼容格式,從而允許更廣泛的字符集合兼容性。 接下來,該函數使用正則表達式刪除了不需要的字符,例如特殊字符和空格。此步驟可確保slug僅包...
    程式設計 發佈於2025-04-17
  • 打造Twitter話題競賽 - 應用註冊指南
    打造Twitter話題競賽 - 應用註冊指南
    Key Takeaways Hosting a contest on Twitter can significantly enhance user interaction and promote a brand or application. This can be achieved by cre...
    程式設計 發佈於2025-04-17
  • 使用PHP cURL發送HTTP POST請求方法
    使用PHP cURL發送HTTP POST請求方法
    php curl http post xport示例此PHP curl示例使用HTTP Post方法將指定的數據發送到遠程服務器。服務器的響應存儲在$ server_output變量中。然後,您可以相應地處理響應,檢查它是否匹配預期結果=確定或處理任何錯誤。
    程式設計 發佈於2025-04-17
  • 左連接為何在右表WHERE子句過濾時像內連接?
    左連接為何在右表WHERE子句過濾時像內連接?
    左JOIN CONUNDRUM:WITCHING小時在數據庫Wizard的領域中變成內在的加入很有趣,當將c.foobar條件放置在上面的Where子句中時,據說左聯接似乎會轉換為內部連接。僅當滿足A.Foo和C.Foobar標準時,才會返回結果。 為什麼要變形?關鍵在於其中的子句。當左聯接的右側...
    程式設計 發佈於2025-04-17
  • 優先隊列:詳細的數據結構和學習
    優先隊列:詳細的數據結構和學習
    Fila Fila, assim como a Pilha, é uma especialização da Lista. Ela basea-se no fundamento FIFO - first in, first out, isso significa que o pri...
    程式設計 發佈於2025-04-17
  • 在GO中構造SQL查詢時,如何安全地加入文本和值?
    在GO中構造SQL查詢時,如何安全地加入文本和值?
    在go中構造文本sql查詢時,在go sql queries 中,在使用conting and contement和contement consem per時,尤其是在使用integer per當per當per時,per per per當per. [&​​&&&&&&&&&&&&&&&默元組方法在...
    程式設計 發佈於2025-04-17
  • 如何解決AppEngine中“無法猜測文件類型,使用application/octet-stream...”錯誤?
    如何解決AppEngine中“無法猜測文件類型,使用application/octet-stream...”錯誤?
    appEngine靜態文件mime type override ,靜態文件處理程序有時可以覆蓋正確的mime類型,在錯誤消息中導致錯誤消息:“無法猜測mimeType for for file for file for [File]。 application/application/octet...
    程式設計 發佈於2025-04-17
  • 解決MySQL錯誤1153:數據包超出'max_allowed_packet'限制
    解決MySQL錯誤1153:數據包超出'max_allowed_packet'限制
    mysql錯誤1153:故障排除比“ max_allowed_pa​​cket” bytes 更大的數據包,用於面對陰謀mysql錯誤1153,同時導入數據capase doft a Database dust?讓我們深入研究罪魁禍首並探索解決方案以糾正此問題。 理解錯誤此錯誤表明在導入過程中...
    程式設計 發佈於2025-04-17
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在Java中的多個返回類型:一種誤解類型:在Java編程中揭示,在Java編程中,Peculiar方法簽名可能會出現,可能會出現,使開發人員陷入困境,使開發人員陷入困境。 getResult(string s); ,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但這確實是如此嗎...
    程式設計 發佈於2025-04-17
  • 如何在Java的全屏獨家模式下處理用戶輸入?
    如何在Java的全屏獨家模式下處理用戶輸入?
    Handling User Input in Full Screen Exclusive Mode in JavaIntroductionWhen running a Java application in full screen exclusive mode, the usual event ha...
    程式設計 發佈於2025-04-17
  • 如何使用Regex在PHP中有效地提取括號內的文本
    如何使用Regex在PHP中有效地提取括號內的文本
    php:在括號內提取文本在處理括號內的文本時,找到最有效的解決方案是必不可少的。一種方法是利用PHP的字符串操作函數,如下所示: 作為替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式來搜索特...
    程式設計 發佈於2025-04-17

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3