实时掌握用户动态:在线人数从哪来
你有没有遇到过这种情况:刚上线一个新功能,想看看有多少人在用,结果后台只显示一堆冷冰冰的注册数,根本不知道此刻到底有多少人真正在操作?这时候,服务器在线用户统计就派上用场了。
所谓在线用户统计,不是看总用户量,而是实时知道当前有多少人正在连接你的服务。比如你做的是一个聊天软件、在线文档工具,或者小游戏平台,这个数据直接反映活跃度和系统压力。
常见实现方式:心跳机制
最常用的方法是“心跳机制”。每个客户端每隔几秒向服务器发一次请求,表示“我还活着”。服务器记录最后一次收到心跳的时间,如果超过设定时间(比如15秒)没收到,就认为用户离线。
举个例子,你在写一个网页应用,前端可以用 setInterval 定时发送请求:
setInterval(() => {
fetch('/api/heartbeat', { method: 'POST' });
}, 10000);后端接收到请求后,更新该用户的最后活跃时间:
// Node.js 示例
app.post('/api/heartbeat', (req, res) => {
const userId = getCurrentUserId(req);
userLastActiveMap.set(userId, Date.now());
res.end();
});统计当前在线人数
有了每个用户的最后活跃时间,统计就简单了。只需要筛选出最近15秒内有过心跳的用户:
function getOnlineCount() {
const now = Date.now();
let count = 0;
for (let [userId, lastTime] of userLastActiveMap) {
if (now - lastTime < 15000) {
count++;
}
}
return count;
}你可以把这个数字通过 WebSocket 推送到管理后台,或者做成图表展示在监控页面上。
考虑真实场景:用户关掉标签页怎么办
用户可能直接关闭浏览器标签,不会主动通知服务器下线。这时候依赖心跳自然超时就好。虽然会有几秒延迟,但在大多数场景下可以接受。
如果想更及时,可以在页面卸载前发送一次退出通知:
window.addEventListener('beforeunload', () => {
navigator.sendBeacon('/api/leave', '');
});但别太依赖这个,因为不是所有浏览器都保证执行。
进阶思路:用 Redis 做分布式存储
如果你的服务部署在多台服务器上,就不能用内存存心跳了。这时候可以把用户活跃时间写入 Redis,并设置自动过期:
SET user:123 active EX 15每次心跳刷新过期时间,Redis 自动清理过期键。统计时用 KEYS 或 SCAN 找出所有未过期的 key 数量即可。
这种方式扩展性好,适合中大型应用。
别忘了轻量化
频繁的心跳会增加服务器负担。如果用户量大,可以适当拉长间隔,比如30秒一次。也可以结合用户行为判断——只有在活跃操作时才上报,减少静默状态下的请求。
在线用户数不只是一个数字,它能帮你判断高峰时段、评估服务器负载、甚至发现异常流量。花点时间加上这个功能,后续运营会轻松不少。