如何高效获取展示Apache2过去10分钟内发起请求的已认证用户列表
实现方案
最高效的方式是在PHP层面直接埋点记录认证用户的活动时间,完全避免解析Apache访问日志带来的高IO、权限适配、日志轮转处理等额外开销,具体可根据你的部署场景选择对应方案:
不推荐直接解析Apache日志实现:日志文件通常体积大、需要PHP进程配置日志读取权限、实时解析匹配的CPU和IO开销远高于直接埋点,仅适合访问量极低的场景。
单节点部署最优解:APCu内存缓存实现
APCu是PHP的进程间共享内存扩展,读写均为内存操作,开销在毫秒级,无磁盘IO消耗
- 先确认服务器已安装并启用APCu扩展,可通过
phpinfo()页面验证 - 在网站全局入口文件(如公共加载文件
init.php、入口index.php的头部)添加埋点逻辑:
// 仅记录通过Basic Auth认证的用户 if (isset($_SERVER['PHP_AUTH_USER'])) { $user = $_SERVER['PHP_AUTH_USER']; $cacheKey = 'active_user_' . $user; // 写入缓存并设置10分钟(600秒)自动过期 apcu_store($cacheKey, time(), 600); }
- 展示活跃用户列表时,直接遍历匹配前缀的缓存键即可:
$activeUsers = []; // 匹配所有活跃用户缓存键 $iterator = new APCUIterator('/^active_user_/'); foreach ($iterator as $cacheItem) { // 二次校验时间,过滤刚到期未被自动清理的缓存 if ($cacheItem['value'] > time() - 600) { $activeUsers[] = substr($cacheItem['key'], 12); } } // 去重后输出 $activeUsers = array_unique($activeUsers);
多节点集群部署最优解:Redis共享存储实现
如果网站部署在多台服务器上,用Redis做跨节点的共享存储即可,逻辑和APCu方案一致:
- 埋点时用
SET 键名 时间戳 EX 600命令写入Redis,设置10分钟自动过期 - 查询时可通过
SCAN命令匹配对应前缀的键,或者用有序集合存储用户活动时间,直接按时间戳范围筛选效率更高
可选优化
如果不需要精确到秒的10分钟统计窗口,可以在埋点逻辑里增加判断:距离该用户上次记录活动时间超过1分钟再写入存储,进一步降低写操作频率。
内容的提问来源于stack exchange,提问作者Tomari
相关产品推荐
相关产品推荐

