From bbfe2afced673712b76442fa875e3c33fd2b9016 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 06:00:50 +0000 Subject: [PATCH 1/5] Initial plan From ef7993c5da94615488b564328a00419f19dc10a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 06:09:28 +0000 Subject: [PATCH 2/5] docs: add rate-limit component documentation for all languages Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com> --- docs/.vitepress/src/en/sidebars.ts | 4 + docs/.vitepress/src/zh-cn/sidebars.ts | 4 + docs/.vitepress/src/zh-hk/sidebars.ts | 4 + docs/.vitepress/src/zh-tw/sidebars.ts | 4 + docs/en/components/rate-limit.md | 466 ++++++++++++++++++++++++++ docs/zh-cn/components/rate-limit.md | 466 ++++++++++++++++++++++++++ docs/zh-hk/components/rate-limit.md | 466 ++++++++++++++++++++++++++ docs/zh-tw/components/rate-limit.md | 466 ++++++++++++++++++++++++++ 8 files changed, 1880 insertions(+) create mode 100644 docs/en/components/rate-limit.md create mode 100644 docs/zh-cn/components/rate-limit.md create mode 100644 docs/zh-hk/components/rate-limit.md create mode 100644 docs/zh-tw/components/rate-limit.md diff --git a/docs/.vitepress/src/en/sidebars.ts b/docs/.vitepress/src/en/sidebars.ts index d0e1033f1..4f0abf961 100644 --- a/docs/.vitepress/src/en/sidebars.ts +++ b/docs/.vitepress/src/en/sidebars.ts @@ -149,6 +149,10 @@ const sidebar:DefaultTheme.Sidebar = { text: 'Purifier', link: '/en/components/purifier.md' }, + { + text: 'Rate Limit', + link: '/en/components/rate-limit.md' + }, { text: 'Recaptcha', link: '/en/components/recaptcha.md' diff --git a/docs/.vitepress/src/zh-cn/sidebars.ts b/docs/.vitepress/src/zh-cn/sidebars.ts index 8a474b958..16c1dc3a1 100644 --- a/docs/.vitepress/src/zh-cn/sidebars.ts +++ b/docs/.vitepress/src/zh-cn/sidebars.ts @@ -162,6 +162,10 @@ const sidebar:DefaultTheme.Sidebar = { text: 'Purifier', link: '/zh-cn/components/purifier.md' }, + { + text: 'Rate Limit', + link: '/zh-cn/components/rate-limit.md' + }, { text: 'Recaptcha', link: '/zh-cn/components/recaptcha.md' diff --git a/docs/.vitepress/src/zh-hk/sidebars.ts b/docs/.vitepress/src/zh-hk/sidebars.ts index 1be4c9620..393d02389 100644 --- a/docs/.vitepress/src/zh-hk/sidebars.ts +++ b/docs/.vitepress/src/zh-hk/sidebars.ts @@ -162,6 +162,10 @@ const sidebar:DefaultTheme.Sidebar = { text: 'Purifier', link: '/zh-hk/components/purifier.md' }, + { + text: 'Rate Limit', + link: '/zh-hk/components/rate-limit.md' + }, { text: 'Recaptcha', link: '/zh-hk/components/recaptcha.md' diff --git a/docs/.vitepress/src/zh-tw/sidebars.ts b/docs/.vitepress/src/zh-tw/sidebars.ts index 5e9faf0e2..3825f87a0 100644 --- a/docs/.vitepress/src/zh-tw/sidebars.ts +++ b/docs/.vitepress/src/zh-tw/sidebars.ts @@ -162,6 +162,10 @@ const sidebar:DefaultTheme.Sidebar = { text: 'Purifier', link: '/zh-tw/components/purifier.md' }, + { + text: 'Rate Limit', + link: '/zh-tw/components/rate-limit.md' + }, { text: 'Recaptcha', link: '/zh-tw/components/recaptcha.md' diff --git a/docs/en/components/rate-limit.md b/docs/en/components/rate-limit.md new file mode 100644 index 000000000..f415c8d4e --- /dev/null +++ b/docs/en/components/rate-limit.md @@ -0,0 +1,466 @@ +# Rate Limit + +Rate limiting component for Hyperf with support for multiple algorithms (Fixed Window, Sliding Window, Token Bucket, Leaky Bucket). + +## Installation + +```bash +composer require friendsofhyperf/rate-limit +``` + +## Requirements + +- Hyperf ~3.1.0 +- Redis + +## Features + +- **Multiple Rate Limiting Algorithms** + - Fixed Window + - Sliding Window + - Token Bucket + - Leaky Bucket +- **Flexible Usage** + - Annotation-based rate limiting via Aspect + - Custom middleware support +- **Smart Order for Multiple Annotations** + - Automatic prioritization of multiple RateLimit annotations + - Intelligent ordering by strictness (maxAttempts/decay ratio) + - More restrictive limits evaluated first for better performance +- **Flexible Key Generation** + - Default method/class-based keys + - Custom key with placeholders support + - Array keys support + - Callable keys support +- **Customizable Responses** + - Custom response message + - Custom HTTP response code +- **Multi Redis Pool Support** + +## Usage + +### Method 1: Using Annotation + +The easiest way to add rate limiting is using the `#[RateLimit]` attribute: + +```php +getClientIp(); + } +} +``` + +Then register the middleware in your config: + +```php +// config/autoload/middlewares.php +return [ + 'http' => [ + App\Middleware\ApiRateLimitMiddleware::class, + ], +]; +``` + +## Rate Limiting Algorithms + +### Fixed Window (Default) + +Simplest algorithm, counts requests in fixed time windows. + +```php +#[RateLimit(algorithm: Algorithm::FIXED_WINDOW)] +``` + +**Pros**: Simple, memory efficient +**Cons**: Can allow burst requests at window boundaries + +### Sliding Window + +More accurate than fixed window, spreads requests evenly. + +```php +#[RateLimit(algorithm: Algorithm::SLIDING_WINDOW)] +``` + +**Pros**: Smooths out bursts, more accurate +**Cons**: Slightly more complex + +### Token Bucket + +Allows burst traffic while maintaining average rate. + +```php +#[RateLimit(algorithm: Algorithm::TOKEN_BUCKET)] +``` + +**Pros**: Allows burst traffic, flexible +**Cons**: Requires more configuration + +### Leaky Bucket + +Processes requests at constant rate, queues bursts. + +```php +#[RateLimit(algorithm: Algorithm::LEAKY_BUCKET)] +``` + +**Pros**: Smooth output rate, prevents bursts +**Cons**: Can delay requests + +## Custom Rate Limiter + +You can implement your own rate limiter by implementing `RateLimiterInterface`: + +```php +index(); +} catch (FriendsOfHyperf\RateLimit\Exception\RateLimitException $e) { + // Rate limit exceeded + $message = $e->getMessage(); // "Too Many Attempts. Please try again in X seconds." + $code = $e->getCode(); // 429 +} +``` + +## Configuration + +The component uses Hyperf's Redis configuration. You can specify which Redis pool to use in the annotation or middleware: + +```php +// Using specific Redis pool +#[RateLimit(pool: 'rate_limit')] +``` + +Make sure to configure your Redis pool in `config/autoload/redis.php`: + +```php +return [ + 'default' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'port' => env('REDIS_PORT', 6379), + 'auth' => env('REDIS_AUTH', null), + 'db' => 0, + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 30, + ], + ], + 'rate_limit' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'port' => env('REDIS_PORT', 6379), + 'auth' => env('REDIS_AUTH', null), + 'db' => 1, + 'pool' => [ + 'min_connections' => 5, + 'max_connections' => 50, + ], + ], +]; +``` + +## Examples + +### Example 1: Login Rate Limiting + +Limit login attempts to prevent brute force attacks: + +```php +#[RateLimit( + key: 'login:{email}', + maxAttempts: 5, + decay: 300, // 5 minutes + response: 'Too many login attempts. Please try again after 5 minutes.', + responseCode: 429 +)] +public function login(string $email, string $password) +{ + // Login logic here +} +``` + +### Example 2: API Endpoint Rate Limit + +Different rate limits for different API endpoints: + +```php +class ApiController +{ + // Public API: 100 requests per minute + #[RateLimit(maxAttempts: 100, decay: 60)] + public function public() + { + // Public endpoint + } + + // Premium API: 1000 requests per minute + #[RateLimit(maxAttempts: 1000, decay: 60)] + public function premium() + { + // Premium endpoint + } +} +``` + +### Example 3: User-based Rate Limiting + +Rate limit per user: + +```php +#[RateLimit( + key: ['user', '{userId}', 'action'], + maxAttempts: 10, + decay: 3600 // 1 hour +)] +public function performAction(int $userId) +{ + // Action logic here +} +``` + +### Example 4: IP-based Rate Limiting + +Rate limit by IP address using middleware: + +```php +class IpRateLimitMiddleware extends RateLimitMiddleware +{ + protected function resolveKey(ServerRequestInterface $request): string + { + return 'ip:' . $this->getClientIp(); + } +} +``` + +### Example 5: Multiple Rate Limits with Smart Order + +Use AutoSort to efficiently handle multiple rate limits on expensive operations: + +```php +class ReportController +{ + /** + * Expensive report generation with multiple protection levels + * AutoSort ensures stricter limits are checked first for better performance + */ + #[AutoSort] + #[RateLimit(maxAttempts: 5, decay: 60, response: 'Too many requests. Max 5 per minute')] // Emergency brake + #[RateLimit(maxAttempts: 30, decay: 3600, response: 'Hourly limit exceeded. Max 30 per hour')] // Sustained load + #[RateLimit(maxAttempts: 100, decay: 86400, response: 'Daily limit exceeded. Max 100 per day')] // Daily cap + public function generateReport($reportType) + { + // Expensive report generation logic here + } +} +``` diff --git a/docs/zh-cn/components/rate-limit.md b/docs/zh-cn/components/rate-limit.md new file mode 100644 index 000000000..4dbf21970 --- /dev/null +++ b/docs/zh-cn/components/rate-limit.md @@ -0,0 +1,466 @@ +# Rate Limit + +Hyperf 的限流组件,支持多种算法(固定窗口、滑动窗口、令牌桶、漏桶)。 + +## 安装 + +```bash +composer require friendsofhyperf/rate-limit +``` + +## 环境要求 + +- Hyperf ~3.1.0 +- Redis + +## 特性 + +- **多种限流算法** + - 固定窗口 + - 滑动窗口 + - 令牌桶 + - 漏桶 +- **灵活的使用方式** + - 基于注解的限流(通过切面实现) + - 自定义中间件支持 +- **多注解智能排序** + - 自动对多个 RateLimit 注解进行优先级排序 + - 根据严格程度智能排序(maxAttempts/decay 比率) + - 更严格的限制优先检查,提升性能 +- **灵活的键生成** + - 默认基于方法/类的键 + - 支持自定义键和占位符 + - 支持数组键 + - 支持可调用键 +- **自定义响应** + - 自定义响应消息 + - 自定义 HTTP 响应码 +- **多 Redis 连接池支持** + +## 使用方式 + +### 方式一:使用注解 + +最简单的方式是使用 `#[RateLimit]` 属性: + +```php +getClientIp(); + } +} +``` + +然后在配置中注册中间件: + +```php +// config/autoload/middlewares.php +return [ + 'http' => [ + App\Middleware\ApiRateLimitMiddleware::class, + ], +]; +``` + +## 限流算法 + +### 固定窗口(默认) + +最简单的算法,在固定时间窗口内计数请求。 + +```php +#[RateLimit(algorithm: Algorithm::FIXED_WINDOW)] +``` + +**优点**:简单,内存高效 +**缺点**:可能在窗口边界处允许突发请求 + +### 滑动窗口 + +比固定窗口更准确,均匀分布请求。 + +```php +#[RateLimit(algorithm: Algorithm::SLIDING_WINDOW)] +``` + +**优点**:平滑突发流量,更准确 +**缺点**:稍微复杂一些 + +### 令牌桶 + +允许突发流量,同时保持平均速率。 + +```php +#[RateLimit(algorithm: Algorithm::TOKEN_BUCKET)] +``` + +**优点**:允许突发流量,灵活 +**缺点**:需要更多配置 + +### 漏桶 + +以恒定速率处理请求,排队突发流量。 + +```php +#[RateLimit(algorithm: Algorithm::LEAKY_BUCKET)] +``` + +**优点**:平滑输出速率,防止突发 +**缺点**:可能延迟请求 + +## 自定义限流器 + +你可以通过实现 `RateLimiterInterface` 来实现自己的限流器: + +```php +index(); +} catch (FriendsOfHyperf\RateLimit\Exception\RateLimitException $e) { + // 超出限流 + $message = $e->getMessage(); // "Too Many Attempts. Please try again in X seconds." + $code = $e->getCode(); // 429 +} +``` + +## 配置 + +组件使用 Hyperf 的 Redis 配置。你可以在注解或中间件中指定使用的 Redis 连接池: + +```php +// 使用特定的 Redis 连接池 +#[RateLimit(pool: 'rate_limit')] +``` + +确保在 `config/autoload/redis.php` 中配置 Redis 连接池: + +```php +return [ + 'default' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'port' => env('REDIS_PORT', 6379), + 'auth' => env('REDIS_AUTH', null), + 'db' => 0, + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 30, + ], + ], + 'rate_limit' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'port' => env('REDIS_PORT', 6379), + 'auth' => env('REDIS_AUTH', null), + 'db' => 1, + 'pool' => [ + 'min_connections' => 5, + 'max_connections' => 50, + ], + ], +]; +``` + +## 示例 + +### 示例 1:登录限流 + +限制登录尝试以防止暴力破解: + +```php +#[RateLimit( + key: 'login:{email}', + maxAttempts: 5, + decay: 300, // 5 分钟 + response: 'Too many login attempts. Please try again after 5 minutes.', + responseCode: 429 +)] +public function login(string $email, string $password) +{ + // 登录逻辑 +} +``` + +### 示例 2:API 端点限流 + +为不同的 API 端点设置不同的限流: + +```php +class ApiController +{ + // 公共 API:每分钟 100 次请求 + #[RateLimit(maxAttempts: 100, decay: 60)] + public function public() + { + // 公共端点 + } + + // 高级 API:每分钟 1000 次请求 + #[RateLimit(maxAttempts: 1000, decay: 60)] + public function premium() + { + // 高级端点 + } +} +``` + +### 示例 3:基于用户的限流 + +按用户限流: + +```php +#[RateLimit( + key: ['user', '{userId}', 'action'], + maxAttempts: 10, + decay: 3600 // 1 小时 +)] +public function performAction(int $userId) +{ + // 操作逻辑 +} +``` + +### 示例 4:基于 IP 的限流 + +使用中间件按 IP 地址限流: + +```php +class IpRateLimitMiddleware extends RateLimitMiddleware +{ + protected function resolveKey(ServerRequestInterface $request): string + { + return 'ip:' . $this->getClientIp(); + } +} +``` + +### 示例 5:使用 AutoSort 的多级限流 + +使用 AutoSort 高效处理昂贵操作的多级限流: + +```php +class ReportController +{ + /** + * 昂贵的报告生成,多级保护 + * AutoSort 确保优先检查严格的限制,提升性能 + */ + #[AutoSort] + #[RateLimit(maxAttempts: 5, decay: 60, response: 'Too many requests. Max 5 per minute')] // 紧急制动 + #[RateLimit(maxAttempts: 30, decay: 3600, response: 'Hourly limit exceeded. Max 30 per hour')] // 持续负载 + #[RateLimit(maxAttempts: 100, decay: 86400, response: 'Daily limit exceeded. Max 100 per day')] // 每日上限 + public function generateReport($reportType) + { + // 昂贵的报告生成逻辑 + } +} +``` diff --git a/docs/zh-hk/components/rate-limit.md b/docs/zh-hk/components/rate-limit.md new file mode 100644 index 000000000..22e91b8dc --- /dev/null +++ b/docs/zh-hk/components/rate-limit.md @@ -0,0 +1,466 @@ +# Rate Limit + +Hyperf 的限流組件,支援多種演算法(固定視窗、滑動視窗、令牌桶、漏桶)。 + +## 安裝 + +```bash +composer require friendsofhyperf/rate-limit +``` + +## 環境需求 + +- Hyperf ~3.1.0 +- Redis + +## 特性 + +- **多種限流演算法** + - 固定視窗 + - 滑動視窗 + - 令牌桶 + - 漏桶 +- **靈活的使用方式** + - 基於註解的限流(透過切面實現) + - 自訂中間件支援 +- **多註解智慧排序** + - 自動對多個 RateLimit 註解進行優先級排序 + - 根據嚴格程度智慧排序(maxAttempts/decay 比率) + - 更嚴格的限制優先檢查,提升效能 +- **靈活的鍵生成** + - 預設基於方法/類別的鍵 + - 支援自訂鍵和佔位符 + - 支援陣列鍵 + - 支援可呼叫鍵 +- **自訂回應** + - 自訂回應訊息 + - 自訂 HTTP 回應碼 +- **多 Redis 連接池支援** + +## 使用方式 + +### 方式一:使用註解 + +最簡單的方式是使用 `#[RateLimit]` 屬性: + +```php +getClientIp(); + } +} +``` + +然後在配置中註冊中間件: + +```php +// config/autoload/middlewares.php +return [ + 'http' => [ + App\Middleware\ApiRateLimitMiddleware::class, + ], +]; +``` + +## 限流演算法 + +### 固定視窗(預設) + +最簡單的演算法,在固定時間視窗內計數請求。 + +```php +#[RateLimit(algorithm: Algorithm::FIXED_WINDOW)] +``` + +**優點**:簡單,內存高效 +**缺點**:可能在視窗邊界處允許突發請求 + +### 滑動視窗 + +比固定視窗更準確,均勻分佈請求。 + +```php +#[RateLimit(algorithm: Algorithm::SLIDING_WINDOW)] +``` + +**優點**:平滑突發流量,更準確 +**缺點**:稍微複雜一些 + +### 令牌桶 + +允許突發流量,同時保持平均速率。 + +```php +#[RateLimit(algorithm: Algorithm::TOKEN_BUCKET)] +``` + +**優點**:允許突發流量,靈活 +**缺點**:需要更多配置 + +### 漏桶 + +以恆定速率處理請求,排隊突發流量。 + +```php +#[RateLimit(algorithm: Algorithm::LEAKY_BUCKET)] +``` + +**優點**:平滑輸出速率,防止突發 +**缺點**:可能延遲請求 + +## 自訂限流器 + +你可以透過實現 `RateLimiterInterface` 來實現自己的限流器: + +```php +index(); +} catch (FriendsOfHyperf\RateLimit\Exception\RateLimitException $e) { + // 超出限流 + $message = $e->getMessage(); // "Too Many Attempts. Please try again in X seconds." + $code = $e->getCode(); // 429 +} +``` + +## 配置 + +組件使用 Hyperf 的 Redis 配置。你可以在註解或中間件中指定使用的 Redis 連接池: + +```php +// 使用特定的 Redis 連接池 +#[RateLimit(pool: 'rate_limit')] +``` + +確保在 `config/autoload/redis.php` 中配置 Redis 連接池: + +```php +return [ + 'default' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'port' => env('REDIS_PORT', 6379), + 'auth' => env('REDIS_AUTH', null), + 'db' => 0, + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 30, + ], + ], + 'rate_limit' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'port' => env('REDIS_PORT', 6379), + 'auth' => env('REDIS_AUTH', null), + 'db' => 1, + 'pool' => [ + 'min_connections' => 5, + 'max_connections' => 50, + ], + ], +]; +``` + +## 示例 + +### 示例 1:登錄限流 + +限制登錄嘗試以防止暴力破解: + +```php +#[RateLimit( + key: 'login:{email}', + maxAttempts: 5, + decay: 300, // 5 分鐘 + response: 'Too many login attempts. Please try again after 5 minutes.', + responseCode: 429 +)] +public function login(string $email, string $password) +{ + // 登錄邏輯 +} +``` + +### 示例 2:API 端點限流 + +為不同的 API 端點設置不同的限流: + +```php +class ApiController +{ + // 公共 API:每分鐘 100 次請求 + #[RateLimit(maxAttempts: 100, decay: 60)] + public function public() + { + // 公共端點 + } + + // 高級 API:每分鐘 1000 次請求 + #[RateLimit(maxAttempts: 1000, decay: 60)] + public function premium() + { + // 高級端點 + } +} +``` + +### 示例 3:基於用戶的限流 + +按用戶限流: + +```php +#[RateLimit( + key: ['user', '{userId}', 'action'], + maxAttempts: 10, + decay: 3600 // 1 小時 +)] +public function performAction(int $userId) +{ + // 操作邏輯 +} +``` + +### 示例 4:基於 IP 的限流 + +使用中間件按 IP 地址限流: + +```php +class IpRateLimitMiddleware extends RateLimitMiddleware +{ + protected function resolveKey(ServerRequestInterface $request): string + { + return 'ip:' . $this->getClientIp(); + } +} +``` + +### 示例 5:使用 AutoSort 的多級限流 + +使用 AutoSort 高效處理昂貴操作的多級限流: + +```php +class ReportController +{ + /** + * 昂貴的報告生成,多級保護 + * AutoSort 確保優先檢查嚴格的限制,提升效能 + */ + #[AutoSort] + #[RateLimit(maxAttempts: 5, decay: 60, response: 'Too many requests. Max 5 per minute')] // 緊急制動 + #[RateLimit(maxAttempts: 30, decay: 3600, response: 'Hourly limit exceeded. Max 30 per hour')] // 持續負載 + #[RateLimit(maxAttempts: 100, decay: 86400, response: 'Daily limit exceeded. Max 100 per day')] // 每日上限 + public function generateReport($reportType) + { + // 昂貴的報告生成邏輯 + } +} +``` diff --git a/docs/zh-tw/components/rate-limit.md b/docs/zh-tw/components/rate-limit.md new file mode 100644 index 000000000..6a88d2f80 --- /dev/null +++ b/docs/zh-tw/components/rate-limit.md @@ -0,0 +1,466 @@ +# Rate Limit + +Hyperf 的限流元件,支援多種演算法(固定視窗、滑動視窗、令牌桶、漏桶)。 + +## 安裝 + +```bash +composer require friendsofhyperf/rate-limit +``` + +## 環境需求 + +- Hyperf ~3.1.0 +- Redis + +## 特性 + +- **多種限流演算法** + - 固定視窗 + - 滑動視窗 + - 令牌桶 + - 漏桶 +- **靈活的使用方式** + - 基於註解的限流(透過切面實現) + - 自訂中介軟體支援 +- **多註解智慧排序** + - 自動對多個 RateLimit 註解進行優先級排序 + - 根據嚴格程度智慧排序(maxAttempts/decay 比率) + - 更嚴格的限制優先檢查,提升效能 +- **靈活的鍵生成** + - 預設基於方法/類別的鍵 + - 支援自訂鍵和佔位符 + - 支援陣列鍵 + - 支援可呼叫鍵 +- **自訂回應** + - 自訂回應訊息 + - 自訂 HTTP 回應碼 +- **多 Redis 連線池支援** + +## 使用方式 + +### 方式一:使用註解 + +最簡單的方式是使用 `#[RateLimit]` 屬性: + +```php +getClientIp(); + } +} +``` + +然後在設定中註冊中介軟體: + +```php +// config/autoload/middlewares.php +return [ + 'http' => [ + App\Middleware\ApiRateLimitMiddleware::class, + ], +]; +``` + +## 限流演算法 + +### 固定視窗(預設) + +最簡單的演算法,在固定時間視窗內計數請求。 + +```php +#[RateLimit(algorithm: Algorithm::FIXED_WINDOW)] +``` + +**優點**:簡單,記憶體高效 +**缺點**:可能在視窗邊界處允許突發請求 + +### 滑動視窗 + +比固定視窗更準確,均勻分佈請求。 + +```php +#[RateLimit(algorithm: Algorithm::SLIDING_WINDOW)] +``` + +**優點**:平滑突發流量,更準確 +**缺點**:稍微複雜一些 + +### 令牌桶 + +允許突發流量,同時保持平均速率。 + +```php +#[RateLimit(algorithm: Algorithm::TOKEN_BUCKET)] +``` + +**優點**:允許突發流量,靈活 +**缺點**:需要更多設定 + +### 漏桶 + +以恆定速率處理請求,排隊突發流量。 + +```php +#[RateLimit(algorithm: Algorithm::LEAKY_BUCKET)] +``` + +**優點**:平滑輸出速率,防止突發 +**缺點**:可能延遲請求 + +## 自訂限流器 + +你可以透過實現 `RateLimiterInterface` 來實現自己的限流器: + +```php +index(); +} catch (FriendsOfHyperf\RateLimit\Exception\RateLimitException $e) { + // 超出限流 + $message = $e->getMessage(); // "Too Many Attempts. Please try again in X seconds." + $code = $e->getCode(); // 429 +} +``` + +## 設定 + +元件使用 Hyperf 的 Redis 設定。你可以在註解或中介軟體中指定使用的 Redis 連線池: + +```php +// 使用特定的 Redis 連線池 +#[RateLimit(pool: 'rate_limit')] +``` + +確保在 `config/autoload/redis.php` 中設定 Redis 連線池: + +```php +return [ + 'default' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'port' => env('REDIS_PORT', 6379), + 'auth' => env('REDIS_AUTH', null), + 'db' => 0, + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 30, + ], + ], + 'rate_limit' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'port' => env('REDIS_PORT', 6379), + 'auth' => env('REDIS_AUTH', null), + 'db' => 1, + 'pool' => [ + 'min_connections' => 5, + 'max_connections' => 50, + ], + ], +]; +``` + +## 範例 + +### 範例 1:登入限流 + +限制登入嘗試以防止暴力破解: + +```php +#[RateLimit( + key: 'login:{email}', + maxAttempts: 5, + decay: 300, // 5 分鐘 + response: 'Too many login attempts. Please try again after 5 minutes.', + responseCode: 429 +)] +public function login(string $email, string $password) +{ + // 登入邏輯 +} +``` + +### 範例 2:API 端點限流 + +為不同的 API 端點設定不同的限流: + +```php +class ApiController +{ + // 公共 API:每分鐘 100 次請求 + #[RateLimit(maxAttempts: 100, decay: 60)] + public function public() + { + // 公共端點 + } + + // 進階 API:每分鐘 1000 次請求 + #[RateLimit(maxAttempts: 1000, decay: 60)] + public function premium() + { + // 進階端點 + } +} +``` + +### 範例 3:基於使用者的限流 + +按使用者限流: + +```php +#[RateLimit( + key: ['user', '{userId}', 'action'], + maxAttempts: 10, + decay: 3600 // 1 小時 +)] +public function performAction(int $userId) +{ + // 操作邏輯 +} +``` + +### 範例 4:基於 IP 的限流 + +使用中介軟體按 IP 位址限流: + +```php +class IpRateLimitMiddleware extends RateLimitMiddleware +{ + protected function resolveKey(ServerRequestInterface $request): string + { + return 'ip:' . $this->getClientIp(); + } +} +``` + +### 範例 5:使用 AutoSort 的多級限流 + +使用 AutoSort 高效處理昂貴操作的多級限流: + +```php +class ReportController +{ + /** + * 昂貴的報告生成,多級保護 + * AutoSort 確保優先檢查嚴格的限制,提升效能 + */ + #[AutoSort] + #[RateLimit(maxAttempts: 5, decay: 60, response: 'Too many requests. Max 5 per minute')] // 緊急制動 + #[RateLimit(maxAttempts: 30, decay: 3600, response: 'Hourly limit exceeded. Max 30 per hour')] // 持續負載 + #[RateLimit(maxAttempts: 100, decay: 86400, response: 'Daily limit exceeded. Max 100 per day')] // 每日上限 + public function generateReport($reportType) + { + // 昂貴的報告生成邏輯 + } +} +``` From 7a1238592c3494e71b0aca96b88cb3b3141d6218 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 06:11:08 +0000 Subject: [PATCH 3/5] docs: fix Traditional Chinese terminology in zh-hk rate-limit documentation Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com> --- docs/zh-hk/components/rate-limit.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh-hk/components/rate-limit.md b/docs/zh-hk/components/rate-limit.md index 22e91b8dc..92826b4ee 100644 --- a/docs/zh-hk/components/rate-limit.md +++ b/docs/zh-hk/components/rate-limit.md @@ -167,7 +167,7 @@ class ApiController } /** - * 不使用 AutoSort 時,按聲明順序檢查 + * 不使用 AutoSort 時,按宣告順序檢查 */ #[RateLimit(maxAttempts: 100, decay: 3600)] // 優先檢查 #[RateLimit(maxAttempts: 10, decay: 60)] // 其次檢查 @@ -183,7 +183,7 @@ class ApiController - **效能**:嚴格的限制優先檢查,避免不必要的寬鬆限制檢查 - **智慧**:自動根據限制嚴格程度(maxAttempts/decay 比率)計算優先級 - **可選**:僅在顯式使用 `AutoSort` 的方法上生效 -- **向後兼容**:現有代碼無需修改即可繼續工作 +- **向後相容**:現有代碼無需修改即可繼續工作 ### 鍵佔位符 From cc70280b13475cef00e205b0d7057624744295f5 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 06:25:53 +0000 Subject: [PATCH 4/5] Update docs and translate --- docs/en/components/rate-limit.md | 146 ++++++++++++++-------------- docs/zh-hk/components/rate-limit.md | 98 +++++++++---------- docs/zh-tw/components/rate-limit.md | 70 ++++++------- 3 files changed, 157 insertions(+), 157 deletions(-) diff --git a/docs/en/components/rate-limit.md b/docs/en/components/rate-limit.md index f415c8d4e..c12621a54 100644 --- a/docs/en/components/rate-limit.md +++ b/docs/en/components/rate-limit.md @@ -1,6 +1,6 @@ # Rate Limit -Rate limiting component for Hyperf with support for multiple algorithms (Fixed Window, Sliding Window, Token Bucket, Leaky Bucket). +Hyperf's rate limiting component, supporting multiple algorithms (fixed window, sliding window, token bucket, leaky bucket). ## Installation @@ -21,27 +21,27 @@ composer require friendsofhyperf/rate-limit - Token Bucket - Leaky Bucket - **Flexible Usage** - - Annotation-based rate limiting via Aspect + - Annotation-based rate limiting (via aspect) - Custom middleware support -- **Smart Order for Multiple Annotations** - - Automatic prioritization of multiple RateLimit annotations - - Intelligent ordering by strictness (maxAttempts/decay ratio) - - More restrictive limits evaluated first for better performance +- **Smart Multi-Annotation Sorting** + - Automatically sorts multiple RateLimit annotations by priority + - Intelligent sorting based on strictness (maxAttempts/decay ratio) + - Stricter limits checked first for better performance - **Flexible Key Generation** - Default method/class-based keys - - Custom key with placeholders support - - Array keys support - - Callable keys support -- **Customizable Responses** - - Custom response message - - Custom HTTP response code -- **Multi Redis Pool Support** + - Support for custom keys and placeholders + - Support for array keys + - Support for callable keys +- **Custom Responses** + - Custom response messages + - Custom HTTP response codes +- **Multiple Redis Connection Pool Support** ## Usage -### Method 1: Using Annotation +### Method 1: Using Annotations -The easiest way to add rate limiting is using the `#[RateLimit]` attribute: +The simplest way is to use the `#[RateLimit]` attribute: ```php getClientIp(); @@ -242,22 +242,22 @@ return [ ]; ``` -## 限流演算法 +## 限流算法 -### 固定視窗(預設) +### 固定窗口(默認) -最簡單的演算法,在固定時間視窗內計數請求。 +最簡單的算法,在固定時間窗口內計數請求。 ```php #[RateLimit(algorithm: Algorithm::FIXED_WINDOW)] ``` **優點**:簡單,內存高效 -**缺點**:可能在視窗邊界處允許突發請求 +**缺點**:可能在窗口邊界處允許突發請求 -### 滑動視窗 +### 滑動窗口 -比固定視窗更準確,均勻分佈請求。 +比固定窗口更準確,均勻分佈請求。 ```php #[RateLimit(algorithm: Algorithm::SLIDING_WINDOW)] @@ -288,9 +288,9 @@ return [ **優點**:平滑輸出速率,防止突發 **缺點**:可能延遲請求 -## 自訂限流器 +## 自定義限流器 -你可以透過實現 `RateLimiterInterface` 來實現自己的限流器: +你可以通過實現 `RateLimiterInterface` 來實現自己的限流器: ```php getClientIp(); @@ -231,7 +231,7 @@ class ApiRateLimitMiddleware extends RateLimitMiddleware } ``` -然後在設定中註冊中介軟體: +然後在配置中註冊中介軟體: ```php // config/autoload/middlewares.php @@ -275,7 +275,7 @@ return [ ``` **優點**:允許突發流量,靈活 -**缺點**:需要更多設定 +**缺點**:需要更多配置 ### 漏桶 @@ -288,7 +288,7 @@ return [ **優點**:平滑輸出速率,防止突發 **缺點**:可能延遲請求 -## 自訂限流器 +## 自定義限流器 你可以透過實現 `RateLimiterInterface` 來實現自己的限流器: @@ -318,9 +318,9 @@ class CustomRateLimiter implements RateLimiterInterface } ``` -## 例外處理 +## 異常處理 -當超出限流時,會拋出 `RateLimitException`: +當超出限流時,會丟擲 `RateLimitException`: ```php Date: Wed, 10 Dec 2025 15:12:36 +0800 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/en/components/rate-limit.md | 2 +- docs/zh-cn/components/rate-limit.md | 2 +- docs/zh-hk/components/rate-limit.md | 2 +- docs/zh-tw/components/rate-limit.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/components/rate-limit.md b/docs/en/components/rate-limit.md index c12621a54..4a45dbe7e 100644 --- a/docs/en/components/rate-limit.md +++ b/docs/en/components/rate-limit.md @@ -139,7 +139,7 @@ class UserController | `decay` | `int` | `60` | Time window in seconds | | `algorithm` | `Algorithm` | `Algorithm::FIXED_WINDOW` | Algorithm: fixed_window, sliding_window, token_bucket, leaky_bucket | | `pool` | `?string` | `null` | Redis connection pool to use | -| `response` | `string` | `'Too Many Attempts.'` | Custom response when rate limit is exceeded | +| `response` | `string` | `'Too Many Attempts, Please try again in %d seconds.'` | Custom response when rate limit is exceeded | | `responseCode` | `int` | `429` | HTTP status code when rate limit is exceeded | ### Using AutoSort for Smart Multi-Rate-Limit Rule Sorting diff --git a/docs/zh-cn/components/rate-limit.md b/docs/zh-cn/components/rate-limit.md index 4dbf21970..5b8d654ef 100644 --- a/docs/zh-cn/components/rate-limit.md +++ b/docs/zh-cn/components/rate-limit.md @@ -139,7 +139,7 @@ class UserController | `decay` | `int` | `60` | 时间窗口(秒) | | `algorithm` | `Algorithm` | `Algorithm::FIXED_WINDOW` | 算法:fixed_window, sliding_window, token_bucket, leaky_bucket | | `pool` | `?string` | `null` | 使用的 Redis 连接池 | -| `response` | `string` | `'Too Many Attempts.'` | 超出限流时的自定义响应 | +| `response` | `string` | `'Too Many Attempts, Please try again in %d seconds.'` | 超出限流时的自定义响应 | | `responseCode` | `int` | `429` | 超出限流时的 HTTP 状态码 | ### 使用 AutoSort 实现多限流规则智能排序 diff --git a/docs/zh-hk/components/rate-limit.md b/docs/zh-hk/components/rate-limit.md index bab99c075..c87bf7016 100644 --- a/docs/zh-hk/components/rate-limit.md +++ b/docs/zh-hk/components/rate-limit.md @@ -139,7 +139,7 @@ class UserController | `decay` | `int` | `60` | 時間窗口(秒) | | `algorithm` | `Algorithm` | `Algorithm::FIXED_WINDOW` | 算法:fixed_window, sliding_window, token_bucket, leaky_bucket | | `pool` | `?string` | `null` | 使用的 Redis 連接池 | -| `response` | `string` | `'Too Many Attempts.'` | 超出限流時的自定義響應 | +| `response` | `string` | `'Too Many Attempts, Please try again in %d seconds.'` | 超出限流時的自定義響應 | | `responseCode` | `int` | `429` | 超出限流時的 HTTP 狀態碼 | ### 使用 AutoSort 實現多限流規則智能排序 diff --git a/docs/zh-tw/components/rate-limit.md b/docs/zh-tw/components/rate-limit.md index c24bb91fb..ecf3c1e2b 100644 --- a/docs/zh-tw/components/rate-limit.md +++ b/docs/zh-tw/components/rate-limit.md @@ -139,7 +139,7 @@ class UserController | `decay` | `int` | `60` | 時間視窗(秒) | | `algorithm` | `Algorithm` | `Algorithm::FIXED_WINDOW` | 演算法:fixed_window, sliding_window, token_bucket, leaky_bucket | | `pool` | `?string` | `null` | 使用的 Redis 連線池 | -| `response` | `string` | `'Too Many Attempts.'` | 超出限流時的自定義響應 | +| `response` | `string` | `'Too Many Attempts, Please try again in %d seconds.'` | 超出限流時的自定義響應 | | `responseCode` | `int` | `429` | 超出限流時的 HTTP 狀態碼 | ### 使用 AutoSort 實現多限流規則智慧排序