本文环境 CentOS8.0,PHP8.1,Nginx1.8,Workerman 4.0\ 不懂的可以评论联系我。 著作权归OwenZhang所有。商业转载请联系OwenZhang获得授权,非商业转载请注明出处。
为防止滥用,你应该考虑对您的 API 限流。 例如,您可以限制每个用户 10 分钟内最多调用 API 100 次。 如果在规定的时间内接收了一个用户大量的请求,将返回响应状态代码 429 (这意味着过多的请求)。
Workerman是一款纯PHP开发的开源高性能的PHP 应用容器。
Workerman不是重复造轮子,它不是一个MVC框架,而是一个更底层更通用的服务框架,你可以用它开发tcp代理、梯子代理、做游戏服务器、邮件服务器、ftp服务器、甚至开发一个php版本的redis、php版本的数据库、php版本的nginx、php版本的php-fpm等等。Workerman可以说是PHP领域的一次创新,让开发者彻底摆脱了PHP只能做WEB的束缚。
实际上Workerman类似一个PHP版本的nginx,核心也是多进程+Epoll+非阻塞IO。Workerman每个进程能维持上万并发连接。由于本身常驻内存,不依赖Apache、nginx、php-fpm这些容器,拥有超高的性能。同时支持TCP、UDP、UNIXSOCKET,支持长连接,支持Websocket、HTTP、WSS、HTTPS等通讯协议以及各种自定义协议。拥有定时器、异步socket客户端、异步Redis、异步Http、异步消息队列等众多高性能组件。
原地址:
https://www.workerman.net/plugin/37
https://github.com/Tinywan/webman-limit-traffic
方便不需要安装composer扩展,哈哈,但还是支持原作者!
\app\middleware\LimitTraffic::class,//令牌桶限流
<?php
/**
* Programmer: Owen Zhang
* Email: owen@owenzhang.com
* Start Date: 05/15/22
* Last Update: 05 15, 2022 [OZ]
* Functions:
* 基于 Lua 脚本简单限流令牌桶,应用接口服务限流工具
* 在原作者的基础上做的修改
* 原地址:
* https://www.workerman.net/plugin/37
* https://github.com/Tinywan/webman-limit-traffic
*/
namespace app\middleware;
use app\common\ApiStatus;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use support\Redis;
class LimitTraffic implements MiddlewareInterface
{
public const LIMIT_TRAFFIC_SCRIPT_SHA = 'limit:traffic:script';
public const LIMIT_TRAFFIC_PRE = 'limit:traffic:pre:';
public function process(Request $request, callable $next): Response
{
if ($result = $this->traffic()) {
return new Response($result['status'], [
'Content-Type' => 'application/json',
], json_encode($result['body']));
}
return $next($request);
}
/**
* 校测
*
* @return array|false
*/
public function traffic()
{
$config = $this->getRateLimit();
$scriptSha = Redis::get(self::LIMIT_TRAFFIC_SCRIPT_SHA);
if (!$scriptSha) {
$script = <<<luascript
local result = redis.call('SETNX', KEYS[1], 1);
if result == 1 then
return redis.call('expire', KEYS[1], ARGV[2])
else
if tonumber(redis.call("GET", KEYS[1])) >= tonumber(ARGV[1]) then
return 0
else
return redis.call("INCR", KEYS[1])
end
end
luascript;
$scriptSha = Redis::script('load', $script);
Redis::set(self::LIMIT_TRAFFIC_SCRIPT_SHA, $scriptSha);
}
$limitKey = self::LIMIT_TRAFFIC_PRE . request()->getRealIp(true);
$result = Redis::rawCommand('evalsha', $scriptSha, 1, $limitKey, $config['limit'], $config['window_time']);
if ($result === 0) {
return [
'limit' => $config['limit'],
'remaining' => $config['limit'] - Redis::get($limitKey),
'reset' => Redis::ttl($limitKey),
'status' => $config['status'],
'body' => $config['body'],
];
}
return false;
}
/**
* @desc : 返回允许的请求的最大数目及时间,例如,[100, 600] 表示在 600 秒内最多 100 次的 API 调
* @author Tinywan(ShaoBo Wan)
*/
public function getRateLimit(): array
{
return [
'limit' => 100, // 请求次数
'window_time' => 5, // 窗口时间,单位:秒
'status' => 429, // HTTP 状态码
'body' => [
// 响应返回的结构信息
'code' => ApiStatus::API_ERROR->value,
'msg' => 'Too Many Requests'
],
];
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有