Limiter (Giới hạn)

Đây là một middleware cho Fiber được sử dụng để giới hạn các yêu cầu lặp đi lặp lại đối với các API công cộng và/hoặc điểm cuối (ví dụ: đặt lại mật khẩu). Đây cũng hữu ích để giới hạn tốc độ của khách hàng API, web crawler hoặc các nhiệm vụ khác đòi hỏi giới hạn tốc độ.

Lưu ý: Middleware này sử dụng gói Storage của chúng tôi để hỗ trợ các cơ sở dữ liệu khác nhau thông qua một giao diện thống nhất. Cấu hình mặc định lưu trữ dữ liệu trong bộ nhớ, và bạn có thể tham khảo ví dụ dưới đây để xem cơ sở dữ liệu khác.

Lưu ý: Theo cấu hình mặc định, mô-đun này không chia sẻ trạng thái với các quy trình/máy chủ khác.

Chữ ký

func New(config ...Config) fiber.Handler

Ví dụ

Nhập gói middleware như một phần của framework web Fiber:

import (
  "github.com/gofiber/fiber/v2"
  "github.com/gofiber/fiber/v2/middleware/limiter"
)

Sau khi tạo ứng dụng Fiber, bạn có thể sử dụng các tùy chọn sau:

// Khởi tạo với cấu hình mặc định
app.Use(limiter.New())

// Hoặc mở rộng với cấu hình tùy chỉnh
app.Use(limiter.New(limiter.Config{
    Next: func(c *fiber.Ctx) bool {
        return c.IP() == "127.0.0.1"
    },
    Max:          20,
    Expiration:     30 * time.Second,
    KeyGenerator:          func(c *fiber.Ctx) string {
        return c.Get("x-forwarded-for")
    },
    LimitReached: func(c *fiber.Ctx) error {
        return c.SendFile("./toofast.html")
    },
    Storage: myCustomStorage{},
}))

Cửa sổ trượt

Bạn có thể kích hoạt thuật toán cửa sổ trượt thay vì sử dụng thuật toán cửa sổ cố định tiêu chuẩn.

Cấu hình ví dụ như sau:

app.Use(limiter.New(limiter.Config{
    Max:            20,
    Expiration:     30 * time.Second,
    LimiterMiddleware: limiter.SlidingWindow{},
}))

Điều này có nghĩa là mỗi cửa sổ sẽ tính đến cửa sổ trước đó (nếu có). Công thức cho tỷ lệ cụ thể là:

weightOfPreviousWindow = số lượng yêu cầu của cửa sổ trước * (whenNewWindow / Expiration)
rate = weightOfPreviousWindow + số lượng yêu cầu của cửa sổ hiện tại

Cấu hình

Thuộc tính Kiểu dữ liệu Mô tả Mặc định
Next func(*fiber.Ctx) bool Next định nghĩa một hàm để bỏ qua middleware này khi trả về true. nil
Max int Số lượng kết nối tối đa trong Expiration giây, trả về phản hồi 429 nếu vượt quá. 5
KeyGenerator func(*fiber.Ctx) string KeyGenerator cho phép bạn tạo ra các khóa tùy chỉnh, mặc định sử dụng c.IP(). Hàm sử dụng c.IP() là giá trị mặc định
Expiration time.Duration Expiration là thời gian giữ hồ sơ yêu cầu trong bộ nhớ. 1 * time.Minute
LimitReached fiber.Handler Được gọi khi giới hạn đạt được. Hàm gửi một phản hồi 429
SkipFailedRequests bool Nếu true, không tính các yêu cầu có StatusCode >= 400. false
SkipSuccessfulRequests bool Nếu true, không tính các yêu cầu có StatusCode < 400. false
Storage fiber.Storage Lưu trữ được sử dụng để lưu trạng thái của middleware. Lưu trữ bộ nhớ chỉ cho quy trình hiện tại
LimiterMiddleware LimiterHandler LimiterMiddleware là cấu trúc thực hiện middleware giới hạn. Một bộ giới hạn tốc độ cửa sổ cố định mới
Duration (Không còn được hỗ trợ) time.Duration Không còn được hỗ trợ: Sử dụng Expiration thay thế. -
Store (Không còn được hỗ trợ) fiber.Storage Không còn được hỗ trợ: Sử dụng Storage thay thế. -
Key (Không còn được hỗ trợ) func(*fiber.Ctx) string Không còn được hỗ trợ: Sử dụng KeyGenerator thay thế. -

Lưu ý: Nếu lưu trữ tùy chỉnh triển khai giao diện Storage, bạn có thể sử dụng lưu trữ tùy chỉnh - để biết thêm thông tin và ví dụ, vui lòng tham khảo tệp store.go.

Cấu hình Mặc định

var ConfigDefault = Config{
    Max:        5,
    Expiration: 1 * time.Minute,
    KeyGenerator: func(c *fiber.Ctx) string {
        return c.IP()
    },
    LimitReached: func(c *fiber.Ctx) error {
        return c.SendStatus(fiber.StatusTooManyRequests)
    },
    SkipFailedRequests: false,
    SkipSuccessfulRequests: false,
    LimiterMiddleware: FixedWindow{},
}

Lưu trữ/Cơ sở dữ liệu tùy chỉnh

Bạn có thể sử dụng bất kỳ phương pháp lưu trữ nào trong gói lưu trữ của chúng tôi.

storage := sqlite3.New() // Từ github.com/gofiber/storage/sqlite3
app.Use(limiter.New(limiter.Config{
    Storage: storage,
}))