kartubi/php-redis-rate 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

kartubi/php-redis-rate

最新稳定版本:v3.0.1

Composer 安装命令:

composer require kartubi/php-redis-rate

包简介

Redis-based rate limiting for PHP/Laravel using GCRA algorithm

README 文档

README

A modern Laravel package for Redis-based rate limiting using the GCRA (Generic Cell Rate Algorithm) algorithm. Built for Laravel 10+ with PHP 8.1+ features. Inspired by and compatible with the go-redis/redis_rate library.

Looking for legacy Laravel support? Check out the v1.x branch for Laravel 5.5-9.x compatibility.

Features

  • GCRA Algorithm: Uses the Generic Cell Rate Algorithm (aka leaky bucket) for precise rate limiting
  • Laravel Integration: Built specifically for Laravel with service providers, facades, and middleware
  • Redis Lua Scripts: Atomic operations using Redis Lua scripts for consistency
  • Flexible Limits: Support for per-second, per-minute, per-hour, and custom rate limits
  • Burst Support: Configure burst capacity independently from rate limits
  • Modern PHP Features: Uses PHP 8.1+ features like readonly properties, named parameters, and match expressions
  • Middleware Support: Ready-to-use middleware for HTTP rate limiting
  • Artisan Commands: Built-in testing commands for debugging rate limits

Installation

Install the package via Composer:

composer require kartubi/php-redis-rate

For legacy Laravel projects (5.5-9.x): Use composer require kartubi/php-redis-rate:^1.0 instead.

The package will automatically register itself via Laravel's package discovery.

Publish the configuration file (optional):

php artisan vendor:publish --tag=redis-rate-config

Clean Redis Keys Setup (Recommended)

By default, Laravel adds an app-name prefix to Redis keys (e.g., laravel-app-database-rate:user123). For cleaner rate limiting keys, run the setup command:

php artisan redis-rate:setup

This command will:

  • ✅ Publish the config/redis-rate.php configuration file
  • ✅ Create a self-contained Redis connection (no changes to config/database.php)
  • ✅ Use a separate Redis database (default: database 2)
  • ✅ Remove Laravel's app-name prefix completely
  • ✅ Result in clean keys like: rate:user123

You can also specify a custom database number:

php artisan redis-rate:setup --database=3

Environment Configuration

After running setup, you can optionally configure these environment variables:

# Redis Rate Limiter Configuration (all optional)
REDIS_RATE_HOST=127.0.0.1      # Redis host
REDIS_RATE_PORT=6379           # Redis port
REDIS_RATE_PASSWORD=null       # Redis password
REDIS_RATE_DB=2                # Redis database for rate limiting
REDIS_RATE_PREFIX=rate:        # Key prefix
REDIS_RATE_TIMEOUT=5.0         # Connection timeout

Docker Configuration

For Docker environments, add these environment variables to your docker-compose.yml:

services:
  your-laravel-app:
    environment:
      # Standard Redis connection
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_PASSWORD=null
      - REDIS_DB=0

      # Redis Rate Limiter (clean keys)
      - REDIS_RATE_HOST=redis
      - REDIS_RATE_PORT=6379
      - REDIS_RATE_DB=2
      - REDIS_RATE_PREFIX=rate

The setup command will run automatically in your Dockerfile:

RUN php artisan redis-rate:setup --force --database=2 || true

Requirements

  • PHP 8.1 or higher
  • Laravel 10.x, 11.x, or 12.x
  • Redis 3.2 or newer (requires replicate_commands feature)
  • Either the Redis PHP extension or Predis 2.0+

Basic Usage

Using the Facade

use Kartubi\RedisRate\Facades\RedisRate;
use Kartubi\RedisRate\Limit;

// Allow 10 requests per second
$result = RedisRate::allow('user:123', Limit::perSecond(10));

if ($result->isAllowed()) {
    // Request is allowed
    echo "Request allowed. Remaining: " . $result->remaining;
} else {
    // Rate limit exceeded
    echo "Rate limit exceeded. Retry after: " . $result->getRetryAfterSeconds() . " seconds";
}

Using Dependency Injection

use Kartubi\RedisRate\RedisRateLimiter;
use Kartubi\RedisRate\Limit;

class ApiController extends Controller
{
    public function __construct(
        private RedisRateLimiter $rateLimiter
    ) {}

    public function handle(Request $request)
    {
        $result = $this->rateLimiter->allow(
            'api:' . $request->ip(),
            Limit::perMinute(60)
        );

        if ($result->isExceeded()) {
            abort(429, 'Too Many Requests');
        }

        // Handle the request...
    }
}

Rate Limit Types

Pre-defined Limits

// 10 requests per second (burst: 10)
$limit = Limit::perSecond(10);

// 60 requests per minute (burst: 60)
$limit = Limit::perMinute(60);

// 1000 requests per hour (burst: 1000)
$limit = Limit::perHour(1000);

Custom Limits

// 100 requests per minute with burst capacity of 150
$limit = Limit::custom(
    rate: 100,           // requests per period
    burst: 150,          // burst capacity
    periodInSeconds: 60  // period in seconds
);

Advanced Usage

Multiple Requests

// Allow up to N requests at once
$result = RedisRate::allowN('bulk:user:123', Limit::perSecond(10), 5);

// Allow at most N requests (partial consumption)
$result = RedisRate::allowAtMost('batch:user:123', Limit::perSecond(10), 8);

Reset Rate Limits

// Reset all limits for a specific key
RedisRate::reset('user:123');

Middleware Usage

Add the middleware to your HTTP kernel or use it directly in routes:

// In routes/api.php
Route::middleware('redis-rate:api')->group(function () {
    Route::get('/users', [UserController::class, 'index']);
});

// With custom limits
Route::middleware('redis-rate:60,api')->get('/search', [SearchController::class, 'search']);

// With custom key
Route::middleware('redis-rate:login,auth:login')->post('/login', [AuthController::class, 'login']);

Register Middleware

In your app/Http/Kernel.php:

protected $routeMiddleware = [
    // ...
    'redis-rate' => \Kartubi\RedisRate\Middleware\RateLimitMiddleware::class,
];

Configuration

The configuration file allows you to customize default settings:

return [
    // Default Redis connection (null uses default)
    'connection' => env('REDIS_RATE_CONNECTION'),

    // Key prefix for Redis keys
    'key_prefix' => env('REDIS_RATE_PREFIX', 'rate:'),

    // Pre-defined rate limits
    'limits' => [
        'api' => [
            'rate' => 60,
            'period' => 60,
            'burst' => 10,
        ],
        'login' => [
            'rate' => 5,
            'period' => 300, // 5 minutes
            'burst' => 5,
        ],
        'upload' => [
            'rate' => 10,
            'period' => 3600, // 1 hour
            'burst' => 20,
        ],
    ],
];

Testing Commands

Test your rate limiting configuration:

# Test with default settings
php artisan redis-rate:test "user:123"

# Test with custom parameters
php artisan redis-rate:test "api:test" --rate=10 --period=60 --burst=15 --requests=12

Understanding Results

The Result object contains important information about the rate limiting decision:

$result = RedisRate::allow('key', $limit);

// Check if request is allowed
$result->isAllowed();    // true if allowed
$result->isExceeded();   // true if rate limit exceeded

// Get remaining capacity
$result->remaining;      // Number of requests remaining

// Get timing information
$result->getRetryAfterSeconds();  // Seconds until next request allowed
$result->getResetAfterSeconds();  // Seconds until rate limit resets

// Get the limit that was applied
$result->limit;          // The Limit object used

Algorithm Details

This package implements the GCRA (Generic Cell Rate Algorithm), also known as the leaky bucket algorithm. GCRA provides several advantages:

  • Smooth rate limiting: Distributes requests evenly over time
  • Burst handling: Allows controlled bursts while maintaining average rate
  • Memory efficient: Uses minimal Redis memory per key
  • Atomic operations: All operations are atomic using Redis Lua scripts

Version Compatibility

Package Version Laravel Version PHP Version Branch
3.x (Current) 10.x, 11.x, 12.x 8.1+ main
1.x (Legacy) 5.5, 6.x, 7.x, 8.x, 9.x 7.2+ v1.x

Note: This is the modern v3.x version. For legacy Laravel support, see the v1.x branch documentation.

Testing

Run the test suite:

composer test

Run tests with coverage:

composer test-coverage

License

This package is open-sourced software licensed under the MIT license.

Credits

This package is inspired by the excellent go-redis/redis_rate library and implements the same GCRA algorithm for PHP/Laravel applications.

统计信息

  • 总下载量: 3
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-09-24