hamburgscleanest / guzzle-advanced-throttle
一个Guzzle中间件,可以根据(多个)定义的规则限制请求。还可以定义缓存策略,例如当超过限制时从缓存中获取响应,或者总是获取缓存值以节省你的限制。
此包的官方仓库似乎已不存在,因此包已被冻结。
Requires
- php: ^8.0
- guzzlehttp/guzzle: ^7.3
- illuminate/cache: ^8
- illuminate/config: ^8
- illuminate/container: ^8
- illuminate/database: ^8
- illuminate/filesystem: ^8
- illuminate/redis: ^8
- predis/predis: ^1.1
- symfony/http-kernel: ^5
Requires (Dev)
- mockery/mockery: ^1
- phpunit/phpunit: ^9
- slope-it/clock-mock: ^0.2.0
README
一个根据(多个)定义的规则限制请求的Guzzle中间件。
还可以定义缓存策略。例如,当超过限制时可以从缓存中读取响应。也可以优先选择缓存值以节省你的限制(force-cache
)。
支持在主机名中使用通配符。
安装
通过Composer
composer require hamburgscleanest/guzzle-advanced-throttle
用法
一般使用
假设你想实施以下规则
每秒20个请求
每2分钟100个请求
- 首先,你必须在
hamburgscleanest\GuzzleAdvancedThrottle\RequestLimitRuleset
中定义规则
$rules = new RequestLimitRuleset([ 'https://www.google.com' => [ [ 'max_requests' => 20, 'request_interval' => 1 ], [ 'max_requests' => 100, 'request_interval' => 120 ] ] ]);
- 你的处理器栈可能看起来像这样
$stack = new HandlerStack(); $stack->setHandler(new CurlHandler());
- 将
hamburgscleanest\GuzzleAdvancedThrottle\Middleware\ThrottleMiddleware
推送到栈中。
它应该是栈中的第一个中间件。
$throttle = new ThrottleMiddleware($rules); // Invoke the middleware $stack->push($throttle()); // OR: alternatively call the handle method directly $stack->push($throttle->handle());
- 将栈传递给客户端
$client = new Client(['base_uri' => 'https://www.google.com', 'handler' => $stack]);
或者base_uri
必须与规则数组中定义的主机相同,或者你必须请求绝对URL,以便中间件能够生效。
// relative $response = $client->get('test'); // absolute $response = $client->get('https://www.google.com/test');
缓存
预先
错误状态码为4xx
或5xx
的响应不会缓存(即使启用了force-cache
)!注意:目前,重定向响应(3xx
)也不会缓存。
可用的存储适配器
array
(默认)
此适配器开箱即用。然而,它不持久化
任何内容。这个适配器仅在同一作用域内工作。它被设置为默认值,因为它不需要额外的配置。
推荐的适配器是laravel
。
laravel
(Illuminate/Cache)- 推荐
你需要为此适配器提供一个配置(Illuminate\Config\Repository
)。
custom
(实现hamburgscleanest\GuzzleAdvancedThrottle\Cache\Interfaces\StorageInterface
)
当你创建一个新的实现时,将类名传递给RequestLimitRuleset::create
方法。你还需要实现任何你实例需要的配置解析。请参阅LaravelAdapter
以获取示例。
用法
$rules = new RequestLimitRuleset( [ ... ], 'force-cache', // caching strategy MyCustomAdapter::class // storage adapter ); $throttle = new ThrottleMiddleware($rules); // Invoke the middleware $stack->push($throttle());
Laravel驱动器
常规设置
可以为每个适配器设置这些值。
'cache' => [ 'ttl' => 900, // How long should responses be cached for (in seconds)? 'allow_empty' => true // When this is set to false, empty responses won't be cached. ]
文件
'cache' => [ 'driver' => 'file', 'options' => [ 'path' => './cache' ], ... ]
Redis
'cache' => [ 'driver' => 'redis', 'options' => [ 'database' => [ 'cluster' => false, 'default' => [ 'host' => '127.0.0.1', 'port' => 6379, 'database' => 0, ], ] ], ... ]
Memcached
'cache' => [ 'driver' => 'memcached', 'options' => [ 'servers' => [ [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100, ], ] ], ... ]
在RequestLimitRuleset的构造函数中传递配置仓库
$rules = new RequestLimitRuleset( [ ... ], 'cache', // caching strategy 'laravel', // storage adapter new Repository(require '../config/laravel-guzzle-limiter.php') // config repository );
将使用相同的适配器来存储内部请求计时器。
可以在规则集中定义适配器
$rules = new RequestLimitRuleset( [ ... ], 'cache', // caching strategy 'array' // storage adapter );
无缓存 - no-cache
仅限制请求。响应不会被缓存。超过限制会导致抛出429 - Too Many Requests
异常。
$rules = new RequestLimitRuleset( [ ... ], 'no-cache', // caching strategy 'array' // storage adapter );
带缓存(默认)- cache
中间件会在抛出429 - Too Many Requests
异常之前尝试回退到缓存的值。
$rules = new RequestLimitRuleset( [ ... ], 'cache', // caching strategy 'array' // storage adapter );
强制缓存 - force-cache
当可用时,始终使用缓存响应以节省您的请求限制。只要当前请求在缓存中有响应,它就返回缓存的响应。只有在缓存中没有响应时,它才会实际发送请求。否则,它会抛出 429 - Too Many Requests
异常。
您可能希望使用此选项禁用空响应的缓存(请参阅 通用驱动器设置)。
$rules = new RequestLimitRuleset( [ ... ], 'force-cache', // caching strategy 'array' // storage adapter );
自定义缓存策略
自定义缓存策略必须实现 CacheStrategy
接口。建议使用 Cacheable
抽象实现基本功能。有关参考实现,请检查 ForceCache
和 Cache
。
要使用新的缓存策略,您需要将完全限定的类名传递给 RequestLimitRuleset
。
用法
$rules = new RequestLimitRuleset([ ... ], MyCustomCacheStrategy::class, 'array', new Repository(...)); $throttle = new ThrottleMiddleware($rules); ...
通配符
如果您想为多个不同的主机定义相同的规则,可以使用通配符。一个可能的用例是子域
$rules = new RequestLimitRuleset([ 'https://www.{subdomain}.mysite.com' => [ [ 'max_requests' => 50, 'request_interval' => 2 ] ] ]);
此 host
匹配 https://www.en.mysite.com
、https://www.de.mysite.com
、https://www.fr.mysite.com
等。
更改
请参阅 变更日志 了解最近发生的更改。
测试
composer test
贡献
安全
如果您发现任何与安全相关的问题,请通过电子邮件 chroma91@gmail.com 联系,而不是使用问题跟踪器。
鸣谢
许可证
MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件。