打开一个购物网站,页面上显示“当前有 328 人正在浏览本商品”,这样的提示你一定不陌生。这背后其实是 web 应用在线用户统计功能在起作用。它不仅能提升用户的信任感,还能为运营提供实时数据支持。
在线用户是怎么定义的?
技术上,“在线”通常指用户在最近一段时间内有过操作行为,比如页面刷新、接口请求等。常见的做法是把“最近 5 分钟内有过活动”的用户算作在线。这个时间窗口可以根据业务灵活调整。
基于会话的轻量级统计方案
对于中小型 web 应用,可以直接利用用户会话(session)信息来做统计。每次用户发起请求时,更新其 session 的最后活跃时间。然后通过查询所有有效 session 中活跃时间在 5 分钟内的数量,即可得到在线人数。
如果使用 MySQL 存储 session,表结构可能长这样:
CREATE TABLE sessions (
id VARCHAR(128) PRIMARY KEY,
user_id INT,
last_active TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_last_active (last_active)
);
统计语句就很简单:
SELECT COUNT(*) FROM sessions
WHERE last_active >= NOW() - INTERVAL 5 MINUTE;
高并发场景下的优化策略
当用户量上升到百万级,频繁读写 session 表会造成数据库压力。这时候可以引入 Redis,用它的自动过期机制来管理在线状态。
每个用户请求时,执行一条命令:
SET user:lastactive:{user_id} 1 EX 300
这条命令设置一个 5 分钟后自动失效的键。统计时只需:
KEYS user:lastactive:*
不过 KEYS 在生产环境慎用,更适合的做法是用 HyperLogLog 或定期异步聚合数据到一个计数器中。
匿名用户也要算进去
很多访客没登录也能浏览页面,这部分人同样要纳入统计。可以给访客分配一个临时 token,存到 cookie 里,作为其唯一标识。后续请求携带该 token,系统就能识别出这是同一个“人”。
例如在 Nginx + Lua 或 Node.js 中间层生成 UUID 并设置 Cookie:
IF cookie.user_token IS EMPTY THEN
SET cookie.user_token = UUID_V4();
END IF;
数据展示别忘了加点“人性化”
直接显示“当前在线:1247 人”显得有点冷。换成“你不是一个人,还有 1246 位朋友正在逛”会更亲切。这种小改动能让数字更有温度,也更容易引发用户互动。
实际开发中,还可以结合地理位置、访问设备等维度做分组统计,比如“来自广东的用户有 89 人在看这款手机”。这些数据对营销活动非常有用。