概述
第一个就是速率控制。某天看到了某个大佬的GO学习笔记里面提到了go的速率控制,根据x/time/rate包来实现的,看了会源码把他粗略的修改过来的
/**
* Created by 993651481.
* User: xydk936
* Date: 2018/6/6
* Time: 下午2:16
*/
//根据go的源码粗略的转过来的了,没做任何的上锁,只支持毫秒
//有bug暂时不解决
$limit = TimeHelper::Every(1000 * 60); //1分钟只让访问两次
$limiter = new Limiter($limit, 2);
$http = new swoole_http_server("127.0.0.1", 9501);
$http->on('request', function ($request, $response) use ($limiter) {
//别问我为什么只会一次应为请求图标了~
if ($limiter->Allow()) {
$code = "pass";
} else {
$code = "stopped";
}
$response->end("
{$code}
");});
echo "浏览器查看结果~" . PHP_EOL;
$http->start();
class Limiter
{
private
$last = 0,
$limit,
$tokens = 0,
$burst;
public function __construct(Limit $r, int $b)
{
$this->limit = $r;
$this->burst = $b;
}
public function Allow(): bool
{
return $this->AllowN(TimeHelper::MilliSecond(), 1);
}
public function AllowN(int $now, int $n): bool
{
return $this->reserveN($now, $n, 0);
}
private function reserveN(int $now, int $n, float $maxFutureReserve): bool
{
$class = $this->advance($now);
echo $class->now, " ", $class->last, " ", $class->tokens . PHP_EOL;
$class->tokens -= floatval($n);
$waitDuration = 0.0;
if ($class->tokens < 0) {
$waitDuration = $this->limit->durationFromTokens(-$class->tokens);
}
$ok = $n <= $this->burst && $waitDuration <= $maxFutureReserve;
if ($ok) {
$this->last = $class->now;
$this->tokens = $class->tokens;
} else {
$this->last = $class->last;
}
return $ok;
}
private function advance(int $now): stdClass
{
$last = $this->last;
if (TimeHelper::Before($now, $last)) {
$last = $now;
}
$maxElapsed = $this->limit->durationFromTokens(floatval($this->burst) - $this->tokens);
//echo $maxElapsed . PHP_EOL;
$elapsed = $now - $last;
//echo $elapsed . PHP_EOL;
//echo $now . " " . $last . " " . $maxElapsed . " " . $elapsed . PHP_EOL;
if ($elapsed > $maxElapsed || $elapsed == 0) {
$elapsed = $maxElapsed;
}
$delta = $this->limit->tokensFromDuration($elapsed);
//var_dump($this->limit->l);
//echo $elapsed, "@", $maxElapsed, "@", $this->burst, "@", $this->tokens, "@", $delta, PHP_EOL;
$tokens = $this->tokens + $delta;
$burst = $this->burst;
if ($tokens > $burst) {
$tokens = $burst;
}
$class = new stdClass();
$class->now = $now;
$class->last = $last;
$class->tokens = $tokens;
//echo $now, ' ', $last, ' ', $maxElapsed, ' ', $elapsed, ' ', $tokens, PHP_EOL;
return $class;
}
}
class Limit
{
public $l;
public function __construct(float $v)
{
$this->l = $v;
}
public function durationFromTokens(float $tokens): float
{
$seconds = $tokens / $this->l;
return $seconds * 1e3;
}
public function tokensFromDuration(int $d): float
{
return TimeHelper::Seconds($d) * $this->l;
}
}
class TimeHelper
{
static function Before(int $t, int $u)
{
return $t < $u || $t == $u && $t < $u;
}
static function Seconds(int $d)
{
$sec = intval($d / 1000);
$nsec = $d % 1000;
return $sec + floatval($nsec) / 1e3;
}
static function Every(int $interval): Limit
{
return new Limit(1 / self::Seconds($interval));
}
static function MilliSecond(): int
{
list($msec, $sec) = explode(' ', microtime());
return (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
}
}
最直观的速率控制莫非就是网页上了。网页上打开会请求图片资源这里说明下
最后
以上就是难过夕阳为你收集整理的php设置 速度,php 速率控制 - 小塔罗的个人空间 - OSCHINA - 中文开源技术交流社区...{$code}的全部内容,希望文章能够帮你解决php设置 速度,php 速率控制 - 小塔罗的个人空间 - OSCHINA - 中文开源技术交流社区...{$code}所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复