Chuyển tới nội dung chính

Plugin Rate Limiting

Plugin Rate Limiting (trên màn hình tạo hiển thị Rate Limit by Request Count, tên kỹ thuật limit-count, nhóm Traffic Control) giới hạn số request được gọi vào API trong một khoảng thời gian. Request vượt hạn ngạch bị từ chối.

Trường hợp sử dụng​

Plugin Rate Limiting bảo vệ backend khỏi quá tải khi traffic tăng đột biến, khi client lỗi gửi request lặp lại liên tục, hoặc khi có hành vi lạm dụng, tấn công.

Các trường hợp điển hình:

  • Giới hạn mỗi địa chỉ IP chỉ được gửi tối đa N request trong một khoảng thời gian.
  • Giới hạn theo từng Consumer đã xác thực: mỗi Consumer có hạn ngạch riêng, không ảnh hưởng lẫn nhau.
  • Giới hạn theo giá trị của một header tùy biến, ví dụ API key trong header X-API-Key.
  • API Gateway chạy nhiều node và cần một hạn ngạch chung chính xác cho toàn cụm: dùng policy là redis thay vì đếm riêng trên từng node.
cảnh báo

Muốn giới hạn theo Consumer (limit_by là consumer), Route / Service phải có sẵn một plugin xác thực như JWT Auth. Request chưa xác thực thì không có Consumer để đếm.

Tạo plugin Rate Limiting​

Để tạo plugin Rate Limiting, bạn thực hiện các bước sau:

  1. Chọn API Gateway → Plugin ở menu bên trái, chọn API Gateway ở góc trên bên phải, nhấn New plugin, rồi chọn Rate Limiting trong popup Add plugin. Bạn cũng có thể thêm từ tab Plugins của Route / Service, xem Thêm Plugin.

  2. Nhập Display Name tại mục Basic Information. Xem Basic Information.

  3. Chọn mục Configuration. Form hiển thị sẵn 8 thuộc tính, kèm khối Quick Start Templates. Ô request_count_limit còn trống (số 100 màu xám chỉ là gợi ý), nên mục Configuration có biểu tượng ⓘ đỏ cho tới khi bạn nhập giá trị.

Mục Configuration của plugin Rate Limiting với Quick Start Templates

AttributeBắt buộcMô tả
request_count_limitYSố request tối đa được phép trong một time_window.
time_windowYĐộ dài cửa sổ đếm: second, minute, hour, day. Mặc định minute.
limit_byYTiêu chí tách bộ đếm, xem bảng Chọn tiêu chí đếm. Mặc định all.
error_codeNMã HTTP trả về khi vượt giới hạn. Mặc định 429.
error_messageNNội dung trả kèm mã lỗi. Mặc định Too many requests, please try again later.
show_rate_limit_headersNGắn header X-RateLimit-Limit và X-RateLimit-Remaining vào response để client biết còn bao nhiêu hạn ngạch. Mặc định true.
continue_on_storage_failureNKhi nơi lưu bộ đếm gặp sự cố thì vẫn cho request đi qua thay vì chặn. Bật lên là ưu tiên tính sẵn sàng hơn độ chính xác của hạn ngạch. Mặc định false.
policyNNơi lưu bộ đếm: local (đếm riêng trên từng node API Gateway) hoặc redis (dùng chung cho cả cụm). Mặc định local.

Nhấn Attribute (8) để bật thêm các thuộc tính khi dùng tới:

Khi limit_by là header:

AttributeBắt buộcMô tả
header_nameYTên HTTP header dùng để nhận diện client, ví dụ X-API-Key. Field này tự được thêm (giá trị rỗng) khi chọn limit_by là header.

Khi policy là redis:

AttributeBắt buộcMô tả
redis_hostYĐịa chỉ Redis server.
redis_portNCổng Redis server.
redis_passwordNMật khẩu kết nối Redis, nếu có.
redis_databaseNChỉ số database Redis sẽ dùng.
redis_cluster_nameNTên cụm Redis mà các node thuộc về.
connection_timeoutNThời gian chờ Redis (mili giây) trước khi coi là lỗi.
enable_sslNMã hóa kết nối tới Redis.
verify_ssl_certificateNKiểm tra chứng chỉ của Redis server, dùng khi bật enable_ssl.

Nhiều mức giới hạn cùng lúc: nhấn + Add Another Limit để khai thêm cặp request_count_limit / time_window trong cùng plugin, ví dụ vừa chặn 100 request / phút để chống gọi dồn dập, vừa chặn 5000 request / ngày để giới hạn tổng mức sử dụng. Khi có từ 2 mức trở lên, các cặp này nằm trong mảng limits, các thuộc tính còn lại (limit_by, error_code, policy…) áp dụng chung cho mọi mức.

Dùng Quick Start Templates (tùy chọn): nhấn Use Template trên thẻ tương ứng.

TemplateDùng khi
Basic API Protection (Local · Single Limit)Giới hạn theo IP, bộ đếm lưu trên từng node, không cần thành phần ngoài. Phù hợp để bảo vệ API công khai khỏi bị gọi dồn dập.
High-Availability Shared Quota (Redis · Multi-Node)Cả cụm API Gateway dùng chung một bộ đếm trên Redis. Nên dùng cho production chạy nhiều node: với policy là local, mỗi node đếm riêng nên hạn ngạch thực tế bị nhân lên theo số node.
cảnh báo

Template High-Availability Shared Quota điền your-redis-host làm giá trị giữ chỗ. Thay bằng địa chỉ Redis thật trước khi nhấn Create.

  1. Chọn mục Scope, chọn Global hoặc Scoped rồi gán Route / Service cần giới hạn. Xem Scope.

  2. Nhấn Create. Thông báo Plugin created successfully hiển thị và plugin xuất hiện trong danh sách với cột Applied to đúng phạm vi đã chọn.

Chọn tiêu chí đếm bằng limit_by​

limit_by quyết định những request nào dùng chung một bộ đếm:

Muốn giới hạn theolimit_byGhi chú
Từng địa chỉ IP clientipPhổ biến nhất cho API công khai. Nhiều client sau cùng một NAT / proxy bị tính chung một IP.
Từng Consumer đã xác thựcconsumerRoute / Service phải có plugin xác thực chạy trước.
Giá trị một header tùy biếnheaderNhập tên header vào header_name, ví dụ X-API-Key.
Kết hợp IP và Consumerip_consumerMỗi cặp (IP, Consumer) một bộ đếm riêng, chặt hơn consumer khi một tài khoản bị dùng từ nhiều nơi.
Toàn bộ traffic chung một hạn ngạchallCẩn thận: request_count_limit lúc này là hạn ngạch cộng dồn của mọi client, không phải của từng client. Đây là giá trị mặc định.
ghi chú

Scope và limit_by là 2 lớp độc lập. Scope quyết định plugin áp dụng cho Route / Service nào. limit_by quyết định bộ đếm được tách theo tiêu chí gì trong số request đã thuộc Scope đó.

Cấu hình mẫu​

Cấu hình khi mới mở form, chưa có request_count_limit:

{
"time_window": "minute",
"limit_by": "all",
"error_code": 429,
"error_message": "Too many requests, please try again later.",
"show_rate_limit_headers": true,
"continue_on_storage_failure": false,
"policy": "local"
}

Template Basic API Protection, giới hạn 100 request / phút theo IP:

{
"request_count_limit": 100,
"time_window": "minute",
"limit_by": "ip",
"error_code": 429,
"error_message": "Too many requests, please try again later.",
"show_rate_limit_headers": true,
"continue_on_storage_failure": false,
"policy": "local"
}

Template High-Availability Shared Quota, dùng chung bộ đếm trên Redis:

{
"request_count_limit": 100,
"time_window": "minute",
"limit_by": "ip",
"error_code": 429,
"error_message": "Too many requests, please try again later.",
"show_rate_limit_headers": true,
"continue_on_storage_failure": false,
"policy": "redis",
"redis_host": "your-redis-host",
"redis_port": 6379,
"redis_password": "",
"redis_database": 0,
"connection_timeout": 1000,
"enable_ssl": false,
"redis_cluster_name": ""
}

Hai mức giới hạn cùng lúc theo IP: 100 request / phút và 5000 request / ngày:

{
"limit_by": "ip",
"error_code": 429,
"error_message": "Too many requests, please try again later.",
"show_rate_limit_headers": true,
"continue_on_storage_failure": false,
"policy": "local",
"limits": [
{
"request_count_limit": 100,
"time_window": "minute"
},
{
"request_count_limit": 5000,
"time_window": "day"
}
]
}

Giới hạn theo từng Consumer đã xác thực, 1000 request / giờ:

{
"request_count_limit": 1000,
"time_window": "hour",
"limit_by": "consumer",
"error_code": 429,
"error_message": "Too many requests, please try again later.",
"show_rate_limit_headers": true,
"continue_on_storage_failure": false,
"policy": "local"
}

Giới hạn theo header X-API-Key, 500 request / phút:

{
"request_count_limit": 500,
"time_window": "minute",
"limit_by": "header",
"header_name": "X-API-Key",
"error_code": 429,
"error_message": "Too many requests, please try again later.",
"show_rate_limit_headers": true,
"continue_on_storage_failure": false,
"policy": "local"
}

Kiểm tra hoạt động​

Gọi liên tiếp API qua Route / Service được áp dụng, vượt quá request_count_limit trong time_window. Các request vượt hạn ngạch nhận mã lỗi bằng error_code (mặc định 429) kèm nội dung error_message. Nếu bật show_rate_limit_headers, mọi response đều kèm X-RateLimit-Limit và X-RateLimit-Remaining, bạn biết còn bao nhiêu lượt mà không phải gọi tới lúc bị chặn.

Lỗi thường gặp​

LỗiNguyên nhânCách xử lý
Mục Configuration có biểu tượng ⓘ đỏ, nút Create không bậtChưa nhập request_count_limit (số màu xám chỉ là gợi ý)Nhập giá trị cho request_count_limit.
Hạn ngạch thực tế cao hơn cấu hình khi chạy nhiều nodepolicy là local, mỗi node đếm riêngDùng policy là redis để cả cụm dùng chung bộ đếm.
Giới hạn theo consumer không có tác dụngRoute / Service chưa có plugin xác thựcThêm plugin xác thực như JWT Auth vào cùng Route / Service.

Bước tiếp theo​

Cập nhật lần cuối vào