apisix~限流外掛的使用

张占岭發表於2024-11-14

參考:

  • https://i4t.com/19399.html
  • https://github.com/apache/apisix/issues/9193
  • https://github.com/apache/apisix/issues/9830
  • https://apisix.apache.org/docs/apisix/plugins/limit-conn/
  • https://blog.frankel.ch/different-rate-limits-apisix/

在 Apache APISIX 中,限流共提供了三種方式,下面說一下

  • limit-req 外掛使用漏桶演算法限制單個客戶端對服務的請求速率
  • limit-conn 外掛用於限制客戶端對單個服務的併發請求數。當客戶端對路由的併發請求數達到限制時,可以返回自定義的狀態碼和響應資訊。
  • limit-count 件使用固定時間視窗演算法,主要用於限制單個客戶端在指定的時間範圍內對服務的總請求數,並且會在 HTTP 響應頭中返回剩餘可以請求的個數。該外掛原理與 GitHub API 的速率限制類似

請求的限制引數

key_type

  • ["var", "var_combination"]
  • var就是一個變更,不需要加$字首
  • var_combination是一組變更的組合,如key為:$http_sub $http_x_forwarded_for

key

  • ["remote_addr", "server_addr", "http_x_real_ip", "http_x_forwarded_for", "consumer_name"]
  • 如果限流標識是在請求頭裡,如請求頭是sub,那麼key可以配置為http_sub

var和var_combination型別對應的配置

  • var_combination
"plugins": {
"limit-req": {
  "burst": 10,
  "key": "$consumer_name $remote_addr",
  "key_type": "var_combination",
  "rate": 2,
  "rejected_code": 502
}
}
  • var
"plugins": {
    "limit-req": {
      "burst": 2,
      "key": "remote_addr",
      "key_type": "var",
      "rate": 3,
      "rejected_code": 502
     },
    "limit-count": {
          "allow_degradation": false,
          "count": 5,
          "key": "http_sub",
          "key_type": "var",
          "policy": "local",
          "rejected_code": 429,
          "rejected_msg": "請求太多了",
          "show_limit_quota_header": true,
          "time_window": 60
        }
}

配置redis

  • redis中key的組成plugin-limit-countroute540160115966214871:2389086815:347c9e9e-076c-45e3-be74-c482fffcc6e5
    • plugin-外掛名route路由id::limit裡的key值
  • 單節點
"plugins": {
    "limit-count": {
        "count": 2,
        "time_window": 60,
        "rejected_code": 503,
        "key": "remote_addr",
        "policy": "redis",
        "redis_host": "127.0.0.1",
        "redis_port": 6379,
        "redis_password": "password",
        "redis_database": 1,
        "redis_timeout": 1001
    }
}
  • 叢集模式
"plugins": {
    "limit-count": {
        "count": 2,
        "time_window": 60,
        "rejected_code": 503,
        "key": "remote_addr",
        "policy": "redis-cluster",
        "redis_cluster_nodes": [
          "127.0.0.1:5000",
          "127.0.0.1:5001"
        ]
    }
}

外掛的解釋

  • limit-req
rate:
    含義:每秒允許的請求數量。
    示例:rate: 3 表示每個客戶端(根據配置的 key)每秒最多可以傳送 3 個請求。

burst:
    含義:突發請求的最大數量。
    示例:burst: 2 表示在短時間內,客戶端可以突發額外的 2 個請求,即在正常速率為 3 的情況下,可以在某些時刻達到 5 個請求(3 + 2)。
  • limit-count
count:
    含義:在指定的時間視窗內允許的最大請求次數。
    示例:count: 2 表示每個客戶端(根據配置的 key)在 time_window 指定的時間段內最多可以傳送 2 個請求。

time_window:
    含義:時間視窗的長度,以秒為單位。
    示例:time_window: 60 表示時間視窗為 60 秒。在這 60 秒內,客戶端最多可以傳送 2 個請求。

對redis-key的解釋

在 APISIX 中使用 limit-count 外掛時,生成的 Redis 鍵通常包含多個部分,這些部分用來標識具體的限流策略和相關資訊。你提到的鍵示例是:

plugin-limit-countroute540160115966214871:2389086815:347c9e9e-076c-45e3-be74-c482fffcc6e5

我們可以將這個鍵分解為幾個部分以便理解:

鍵的組成部分

  1. plugin-limit-count

    • 這是固定的字首,表示該鍵是由 limit-count 外掛生成的。
  2. route540160115966214871

    • 這一部分通常表示與特定路由(route)相關的資訊。
    • 540160115966214871 是路由的唯一識別符號(ID),它對應於 APISIX 中配置的某個具體路由。這使得限流策略能夠應用於特定的路由。
  3. 2389086815

    • 這一部分通常表示限流的維度或時間視窗的識別符號,可能是一個時間戳或者是請求計數的某一部分。
    • 具體含義取決於你的限流配置,比如它可能是用於區分不同時間段內的請求計數。
  4. 347c9e9e-076c-45e3-be74-c482fffcc6e5

    • 這一部分一般是使用者識別符號(如客戶端 ID 或者其他唯一識別符號),用於在限流策略中區分不同的使用者或客戶端。
    • 這種設計允許對不同的使用者或客戶端分別進行限流控制。

總結

整個鍵的結構是為了確保每個限流例項都是唯一的,並且能夠精確地與特定的路由和使用者關聯。透過這樣的設計,APISIX 可以高效地管理和應用限流策略,以保障系統的穩定性和效能。

redis-count和redis-req的使用場景

漏桶演算法(Leaky Bucket)和固定視窗限流(Fixed Window)是兩種常見的限流策略,它們適用於不同的使用場景。以下是這兩種限流策略的特點及其適用場景:

漏桶演算法(Leaky Bucket)

特點:

  • 平滑輸出:漏桶演算法允許請求以固定速率被處理,儘管輸入請求可以是不規則的。
  • 水位限制:桶內有一個容量限制,當達到上限時,多餘的請求將被丟棄或拒絕。
  • 時間延遲:由於請求是以固定速率“漏出”的,因此可能會引入一定的延遲。

使用場景:

  1. 網路流量控制:適合需要平穩流量輸出的場景,如影片流、音訊流等。
  2. API呼叫限制:在需要防止突發流量對後端服務造成影響的情況下,可以使用漏桶演算法來平衡請求量。
  3. 實時資料處理:適合處理實時資料流的場景,例如訊息佇列中的訊息消費。
  4. 使用者行為限制:例如限制使用者在一定時間內的操作次數,以防止刷票、刷單等行為。

固定視窗限流(Fixed Window)

特點:

  • 時間視窗:將時間劃分為固定長度的視窗,在每個視窗內允許一定數量的請求。
  • 突發性:在視窗開始時,所有請求都可以瞬間進入,但在視窗結束前不會再接受新的請求,直到下一個視窗開始。
  • 簡單易實現:相對其他限流演算法,固定視窗的實現較為簡單。

使用場景:

  1. 日常訪問控制:適合控制使用者在特定時間段內的訪問頻率,比如限制使用者每天的登入次數。
  2. API介面呼叫:用於限制外部系統對內部API的呼叫頻率,確保系統穩定性。
  3. 短時間高併發場景:如電商促銷活動期間,可以快速處理大量請求,但需要限制每個使用者的請求頻率。
  4. 統計分析:適合進行簡單的統計計算,如記錄某一時間視窗內的訪問量。

總結

  • 漏桶演算法更適合需要平滑流量控制的場景,能夠有效防止突發流量造成的系統壓力。
  • 固定視窗限流則適合短時間內的請求控制,簡單易用,適合一些對時間視窗要求不嚴格的應用。

根據具體的業務需求和系統架構,可以選擇合適的限流策略來保障系統的穩定性和可用性。

相關文章