nimbly/throttler 问题修复 & 功能扩展

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

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

nimbly/throttler

Composer 安装命令:

composer require nimbly/throttler

包简介

A framework agnostic rate limiter.

README 文档

README

Latest Stable Version Build Status License

A framework agnostic request rate limiter.

Description

Throttler can rate limit on any data point you like: IP address, user ID, API key, or any other uniquely identifying information you have access to.

Installation

composer require nimbly/throttler

Usage

Storage adapter

You need a place to keep track of the hit counters - cache, database, or whatever. Create an instance of a storage adapter to be passed into the Throttler. See the Available storage adapters section further down for complete list of adapters.

$storageAdapter = new Throttler\Adapters\Redis(
    new Predis\Client('tcp://localhost:6379')
);

Throttler

Instantiate Throttler by passing in a storage adapter instance.

$throttler = new Throttler($storageAdapter);

Constructor Options

You may pass in an array of key => value pair options as the second parameter of the constructor.

$throttler = new Throttler($storageAdapter, ['key' => 'value']);

Supported options:

  • prefix Prefix to apply to all keys and passed to the storage adapter. Defaults to Throttler\.

Methods

hit(string $id, int $limit, int $decay) : boolean

Log a hit on the throttler incrementing the rate limit counter. Returns true on success and false on failure.

  • id is the unique ID of the source of this request. This value can be any string you'd like: IP address, a user ID, etc.
  • limit is the total number of requests allowed over the timespan defined by decay.
  • decay is the timespan allowed in seconds.

This example allows 120 requests in a 60 second timespan per IP address.

if( $throttler->hit($request->ipAddress(), 120, 60) === false ){
    throw new TooManyRequestsHttpException(60, 'Slow it down man!');
}

check(string $id) : int

Check (but do not increment) the current rate limit counter for the given ID.

if( $throttler->check($request->user->id) >= $warningThreshold ){
    $response = $response->withHeader("X-Rate-Limit", "Warning");
}

Middleware

Add the throttler to your Middleware (you're using Middleware, right?)

class ThrottleRequest implements SomeMiddlewareLibrary
{
    public function handle(Request $request, $next)
    {
        $storageAdapter = new Throttler\Adapters\Redis(
            new Predis\Client('tcp://localhost:6379')
        );

        $throttler = new Throttler($storageAdapter);

        if( $throttler->hit($request->ipAddress(), 120, 60) === false ){
            throw new TooManyRequestsHttpException(60, 'Slow it down man!');
        }

        return $next($request);
    }
}

Available storage adapters

The following list of storage adapters are provided "out of the box":

Redis

Requires the Predis library available via predis/predis on Packagist.

$redisAdapter = new Throttler\Adapters\Redis(
    new Predis\Client("tcp://localhost:6379")
);

$throttler = new Throttler($redisAdapter);

Database

The database adapter can use any PDO compatible database to persist throttler data. Just add this table to your database:

CREATE TABLE throttler
(
    key VARCHAR(64) PRIMARY KEY,
    hits INTEGER UNSIGNED NOT NULL DEFAULT 1,
    expires_at INTEGER UNSIGNED NOT NULL
)
$databaseAdapter = new Throttler\Adapters\Database(
    new PDO("mysql:dbname=myapp;host=localhost", "username", "password")
);

$throttler = new Throttler($databaseAdapter);

You can also customize the columns that the Throttler will use along with garbage collection chance:

  • table Table name to use. Defaults to throttler.
  • key Key column name. Column type must be a string or varchar. Defaults to key.
  • hits Hits column name. Column type must be an integer. Defaults to hits.
  • expires_at Expiration column name. Column type must be an integer (UNIX timestamp). Defaults to expires_at.
  • gc_chance Percent chance that garbage collection will run. A value less than 1 means it will never run. A value greater than 99 means it will run on every call. Defaults to 5.
$databaseAdapter = new Throttler\Adapters\Database(
    new PDO("mysql:dbname=myapp;host=localhost", "username", "password"),
    [
        "table" => "limiter",
        "key" => "id",
        "hits" => "value",
        "expires_at" => "ttl",
        "gc_chance" => 20,
    ]
);

$throttler = new Throttler($databaseAdapter);

APCu

APCu is an in-memory PHP cache and requires the PECL APCu library available through most Linux package managers.

$apcuAdapter = new Throttler\Adapters\Apcu;

$throttler = new Throttler($apcuAdapter);

Memory

The memory adapter maintains its throttler purely in memory and does not persist its data between HTTP or CLI requets. This adapter is ideal for testing or other special use cases. Only use this adapter if you know what you are doing.

$memoryAdapter = new Throttler\Adapters\Memory;

$throttler = new Throttler($memoryAdapter);

Custom storage adapters

A Throttler\StorageAdapter interface is provided so that you may create your own adapters for any persistance engine you want. It must implement two methods:

get(string $key) : int

Returns the given key's current counter or 0 if key does not exist.

increment(string $key, int $decay) : int

Increments the counter for the given key. If key does not exist, it must create it and set its counter to 1 as well as set the counter to expire after $decay seconds. Returns the counter value.

use Nimbly\Throttler\StorageAdapter;

class MyStorageAdapter implements StorageAdapter
{
    public function get(string $key): int
    {
        // Get $key from storage engine.
    }

    public function increment(string $key, int $decay): int
    {
        // Increment $key on storage engine and return new value.
    }
}

nimbly/throttler 适用场景与选型建议

nimbly/throttler 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 6.58k 次下载、GitHub Stars 达 0, 最近一次更新时间为 2018 年 10 月 27 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 nimbly/throttler 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 nimbly/throttler 我们能提供哪些服务?
定制开发 / 二次开发

基于 nimbly/throttler 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2018-10-27