Skip to content

Commit 75494da

Browse files
committed
Merge branch 'dev'
2 parents 23dcbd4 + 058968f commit 75494da

File tree

6 files changed

+85
-73
lines changed

6 files changed

+85
-73
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
本组件仅支持使用 `Redis` 作为中间件,可以针对方法、接口设置限流,通过设置`总容量、单位时间内生成填充的数量、每次扣除数量`实现限流。
1313

14+
> 本仓库仅用于浏览,不接受 issue 和 Pull Requests,请前往:<https://github.com/Yurunsoft/imi>
15+
1416
## Composer
1517

1618
本项目可以使用composer安装,遵循psr-4自动加载规则,在你的 `composer.json` 中加入下面的内容:

composer.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@
66
"require": {
77
"bandwidth-throttle/token-bucket": "^2.0"
88
},
9-
"require-dev": {
10-
"yurunsoft/imi": "dev-dev"
11-
},
9+
"require-dev": {},
1210
"autoload": {
13-
"psr-4" : {
14-
"Imi\\RateLimit\\" : "src/"
11+
"psr-4": {
12+
"Imi\\RateLimit\\": "src/"
1513
}
1614
}
17-
}
15+
}

src/Main.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace Imi\RateLimit;
34

45
use Imi\Main\BaseMain;
@@ -7,6 +8,5 @@ class Main extends BaseMain
78
{
89
public function __init()
910
{
10-
1111
}
1212
}

src/RateLimiter.php

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,46 @@
11
<?php
2+
23
namespace Imi\RateLimit;
34

4-
use Imi\Redis\RedisManager;
5+
use bandwidthThrottle\tokenBucket\BlockingConsumer;
56
use bandwidthThrottle\tokenBucket\Rate;
6-
use Imi\RateLimit\Storage\ImiRedisStorage;
7+
use bandwidthThrottle\tokenBucket\TimeoutException;
78
use bandwidthThrottle\tokenBucket\TokenBucket;
89
use Imi\RateLimit\Exception\RateLimitException;
9-
use bandwidthThrottle\tokenBucket\BlockingConsumer;
10-
use bandwidthThrottle\tokenBucket\TimeoutException;
10+
use Imi\RateLimit\Storage\ImiRedisStorage;
11+
use Imi\Redis\RedisManager;
1112

1213
/**
13-
* 限流器手动调用类
14+
* 限流器手动调用类.
1415
*/
1516
abstract class RateLimiter
1617
{
1718
/**
1819
* 限流
1920
*
20-
* @param string $name 限流器名称
21-
* @param int $capacity 总容量
21+
* @param string $name 限流器名称
22+
* @param int $capacity 总容量
2223
* @param callable $callback 触发限流的回调
23-
* @param int $fill 单位时间内生成填充的数量,不设置或为null时,默认值与 $capacity 相同
24-
* @param string $unit 单位时间,默认为:秒(second),支持:microsecond、millisecond、second、minute、hour、day、week、month、year
25-
* @param integer $deduct 每次扣除数量,默认为1
26-
* @param string $poolName 连接池名称,留空取默认 redis 连接池
24+
* @param int $fill 单位时间内生成填充的数量,不设置或为null时,默认值与 $capacity 相同
25+
* @param string $unit 单位时间,默认为:秒(second),支持:microsecond、millisecond、second、minute、hour、day、week、month、year
26+
* @param int $deduct 每次扣除数量,默认为1
27+
* @param string $poolName 连接池名称,留空取默认 redis 连接池
28+
*
2729
* @return mixed
2830
*/
2931
public static function limit($name, $capacity, $callback = null, $fill = null, $unit = 'second', $deduct = 1, $poolName = null)
3032
{
31-
if(null === $fill)
33+
if (null === $fill)
3234
{
3335
$fill = $capacity;
3436
}
3537
$storage = new ImiRedisStorage($name, RedisManager::getInstance($poolName));
36-
$rate = new Rate($fill, $unit);
37-
$bucket = new TokenBucket($capacity, $rate, $storage);
38+
$rate = new Rate($fill, $unit);
39+
$bucket = new TokenBucket($capacity, $rate, $storage);
3840
$bucket->bootstrap($capacity);
39-
if(!$bucket->consume($deduct))
41+
if (!$bucket->consume($deduct))
4042
{
41-
if($callback)
43+
if ($callback)
4244
{
4345
return $callback($name);
4446
}
@@ -54,34 +56,39 @@ public static function limit($name, $capacity, $callback = null, $fill = null, $
5456
}
5557

5658
/**
57-
* 限流,允许超时等待
59+
* 限流,允许超时等待.
5860
*
59-
* @param string $name 限流器名称
60-
* @param int $capacity 总容量
61-
* @param callable $callback 触发限流的回调
61+
* @param string $name 限流器名称
62+
* @param int $capacity 总容量
63+
* @param callable $callback 触发限流的回调
6264
* @param int|null $blockingTimeout 超时时间,单位:秒;为 null 不限制
63-
* @param int $fill 单位时间内生成填充的数量,不设置或为null时,默认值与 $capacity 相同
64-
* @param string $unit 单位时间,默认为:秒(second),支持:microsecond、millisecond、second、minute、hour、day、week、month、year
65-
* @param integer $deduct 每次扣除数量,默认为1
66-
* @param string $poolName 连接池名称,留空取默认 redis 连接池
65+
* @param int $fill 单位时间内生成填充的数量,不设置或为null时,默认值与 $capacity 相同
66+
* @param string $unit 单位时间,默认为:秒(second),支持:microsecond、millisecond、second、minute、hour、day、week、month、year
67+
* @param int $deduct 每次扣除数量,默认为1
68+
* @param string $poolName 连接池名称,留空取默认 redis 连接池
69+
*
6770
* @return mixed
6871
*/
6972
public static function limitBlock($name, $capacity, $callback = null, $blockingTimeout = null, $fill = null, $unit = 'second', $deduct = 1, $poolName = null)
7073
{
71-
if(null === $fill)
74+
if (null === $fill)
7275
{
7376
$fill = $capacity;
7477
}
7578
$storage = new ImiRedisStorage($name, RedisManager::getInstance($poolName), $blockingTimeout);
76-
$rate = new Rate($fill, $unit);
77-
$bucket = new TokenBucket($capacity, $rate, $storage);
79+
$rate = new Rate($fill, $unit);
80+
$bucket = new TokenBucket($capacity, $rate, $storage);
7881
$bucket->bootstrap($capacity);
7982
$consumer = new BlockingConsumer($bucket, $blockingTimeout);
80-
try{
83+
try
84+
{
8185
$consumer->consume($deduct);
86+
8287
return true;
83-
} catch(TimeoutException $ex) {
84-
if($callback)
88+
}
89+
catch (TimeoutException $ex)
90+
{
91+
if ($callback)
8592
{
8693
return $callback($name);
8794
}
@@ -93,10 +100,11 @@ public static function limitBlock($name, $capacity, $callback = null, $blockingT
93100
}
94101

95102
/**
96-
* 默认限流回调
103+
* 默认限流回调.
97104
*
98105
* @param string $name 限流器名称
99-
* @return void
106+
*
107+
* @return mixed
100108
*/
101109
public static function defaultCallback($name)
102110
{

src/WorkerLimiter.php

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,33 @@
11
<?php
2+
23
namespace Imi\RateLimit;
34

4-
use Imi\Pool\PoolManager;
5-
use Imi\Redis\RedisManager;
6-
use bandwidthThrottle\tokenBucket\TokenBucket;
75
use Imi\RateLimit\Exception\RateLimitException;
8-
use bandwidthThrottle\tokenBucket\BlockingConsumer;
9-
use bandwidthThrottle\tokenBucket\TimeoutException;
106

117
/**
12-
* 并发工作数限流器手动调用类
8+
* 并发工作数限流器手动调用类.
139
*/
1410
abstract class WorkerLimiter
1511
{
1612
/**
1713
* 限流执行任务
1814
*
19-
* @param callable $callable 任务回调
20-
* @param string $name 限流器名称
21-
* @param int $max 最大同时运行任务数
22-
* @param float $timeout 超时时间,单位:秒;为 null 不限制
23-
* @param callable $callback 触发限流的回调
15+
* @param callable $callable 任务回调
16+
* @param string $name 限流器名称
17+
* @param int $max 最大同时运行任务数
18+
* @param float $timeout 超时时间,单位:秒;为 null 不限制
19+
* @param callable $callback 触发限流的回调
2420
* @param string|null $poolName 连接池名称,留空取默认 redis 连接池
21+
*
2522
* @return mixed
2623
*/
2724
public static function call($callable, $name, $max, $timeout = null, $callback = null, $poolName = null)
2825
{
2926
// 加锁
3027
$workerId = WorkerLimiterLock::lock($name, $max, $timeout, $poolName);
31-
if(false === $workerId)
28+
if (false === $workerId)
3229
{
33-
if($callback)
30+
if ($callback)
3431
{
3532
return $callback($name);
3633
}
@@ -43,48 +40,52 @@ public static function call($callable, $name, $max, $timeout = null, $callback =
4340
$result = $callable();
4441
// 释放
4542
WorkerLimiterLock::unlock($name, $workerId, $poolName);
43+
4644
return $result;
4745
}
4846

4947
/**
50-
* 限流执行任务,允许超时等待
48+
* 限流执行任务,允许超时等待.
49+
*
50+
* @param callable $callable 任务回调
51+
* @param string $name 限流器名称
52+
* @param int $max 最大同时运行任务数
53+
* @param float $timeout 任务超时时间,单位:秒;为 null 不限制
54+
* @param float $blockingTimeout 等待重试超时时间,单位:秒;为 null 不限制
55+
* @param callable $callback 触发限流的回调
56+
* @param string|null $poolName 连接池名称,留空取默认 redis 连接池
5157
*
52-
* @param callable $callable 任务回调
53-
* @param string $name 限流器名称
54-
* @param int $max 最大同时运行任务数
55-
* @param float $timeout 任务超时时间,单位:秒;为 null 不限制
56-
* @param float $blockingTimeout 等待重试超时时间,单位:秒;为 null 不限制
57-
* @param callable $callback 触发限流的回调
58-
* @param string|null $poolName 连接池名称,留空取默认 redis 连接池
5958
* @return mixed
6059
*/
6160
public static function callBlock($callable, $name, $max, $timeout = null, $blockingTimeout = null, $callback = null, $poolName = null)
6261
{
63-
if(null === $blockingTimeout)
62+
if (null === $blockingTimeout)
6463
{
65-
$blockingTimeout = PHP_INT_MAX;
64+
$blockingTimeout = \PHP_INT_MAX;
6665
}
6766
$isBlockingRetry = false;
68-
do {
67+
$beginBlockingRetryTime = 0;
68+
do
69+
{
6970
// 加锁
7071
$workerId = WorkerLimiterLock::lock($name, $max, $timeout, $poolName);
71-
if(false === $workerId)
72+
if (false === $workerId)
7273
{
73-
if(!$isBlockingRetry)
74+
if (!$isBlockingRetry)
7475
{
7576
$beginBlockingRetryTime = microtime(true);
7677
$isBlockingRetry = true;
7778
}
7879
$leftSleep = microtime(true) - $beginBlockingRetryTime;
79-
if($leftSleep > 0)
80+
if ($leftSleep > 0)
8081
{
8182
// 等待随机1-10毫秒数后重试
8283
usleep(min(mt_rand(1000, 10000), $leftSleep * 1000));
8384
}
8485
else
8586
{
8687
// 触发限流的回调
87-
if($callback)
88+
if ($callback)
8889
{
8990
return $callback($name);
9091
}
@@ -99,18 +100,20 @@ public static function callBlock($callable, $name, $max, $timeout = null, $block
99100
$result = $callable();
100101
// 释放
101102
WorkerLimiterLock::unlock($name, $workerId, $poolName);
103+
102104
return $result;
103-
} while(true);
105+
} while (true);
104106
}
105107

106108
/**
107-
* 默认限流回调
109+
* 默认限流回调.
108110
*
109111
* @param string $name 限流器名称
110-
* @return void
112+
*
113+
* @return mixed
111114
*/
112115
public static function defaultCallback($name)
113116
{
114117
throw new RateLimitException(sprintf('%s Worker Limit', $name));
115118
}
116-
}
119+
}

src/config/config.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
2+
23
return [
3-
'beanScan' => [
4+
'beanScan' => [
45
'Imi\RateLimit\Annotation',
56
'Imi\RateLimit\Aspect',
67
],
7-
];
8+
];

0 commit comments

Comments
 (0)