要准确统计请求频次,需在中间件中主动用Cache::inc()递增计数并设60秒TTL,标准化route(去query、统一大写),导出数据时单点查询避免KEYS阻塞,返回前强制(int)转换count字段确保ECharts正确渲染。
ThinkPHP 6 的
中间件怎么用才不漏统计?
默认的
中间件只做拦截,不记录原始请求频次——你看到“429 Too Many Requests”,但查不到用户过去1分钟到底发了多少次。要统计,得自己接管计数逻辑。
推荐在中间件里手动调用缓存递增,而不是依赖
的内置判断:
用
主动累加,比读-改-写更原子
配合
初始化(仅首次),避免空值导致递增失败
注意
要标准化:去掉 query 参数、统一大小写,否则
和
会被算作不同接口
如何把限流数据导出成 JSON 供 ECharts 渲染?
别直接查 Redis keys——
在生产环境会阻塞主线程。应该用前缀扫描 + 分页拉取:
用
单点查,配合前端传来的
和
查询条件
后台接口返回结构示例:
前端用
每30秒轮询一次,避免 WebSocket 增加部署复杂度
Redis 缓存键设计不当会导致统计错乱?
常见错误是把时间窗口硬编码进 key,比如
——这会让每小时/每天生成新 key,无法滚动统计最近60秒。
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
立即学习
“
PHP免费学习笔记(深入)
”;
正确做法:key 不含时间戳,靠缓存 TTL 控制生命周期,例如
如果需要多维度(如按用户ID+IP+接口),用冒号拼接但保持层级清晰:
特别注意:Redis 的
对不存在的 key 默认设为 1,所以首次调用
就能自动初始化,无需先
为什么 ECharts 折线图总显示“无数据”?
大概率是后端返回的
字段是字符串类型(Redis 返回的都是 string),而 ECharts 的
要求数值数组。
前端必须显式转换:
后端接口建议统一 cast:
,避免 PHP 自动类型转换在某些版本下行为不一致
测试时用
直接看原始响应,比在浏览器里调试更快
真正难的不是画图,而是确保每一行数据都来自同一时间粒度、同一聚合口径。比如你用 60 秒 TTL,但前端每 10 秒拉一次,又没做服务端去重,图表就会抖动。这种细节,文档里通常不提。
throttlethrottlethrottleCache::inc('api:rate:'.$ip.':'.$route, 1)Cache::set($key, 0, 60)$route/user?id=1/user?id=2KEYS api:rate:*Cache::get('api:rate:'.$ip.':'.$route)iproute{"data":[{"ip":"192.168.1.100","route":"/api/v1/order","count":17,"expire":53}]}setIntervalapi:rate:20240520:192.168.1.100Cache::set($key, $count, 60)api:rate:user_123:192.168.1.100:/orderINCRCache::inc()set(0)countseries.datadata: res.data.map(d => Number(d.count))'count' => (int) $valuecurl -v http://your.app/api/rate?ip=192.168.1.100