统计在线用户的数量,是应用很常见的需求了。如果需要精准的统计到用户是在线,离线状态,我想只有客户端和服务器通过保持一个TCP长连接来实现。如果应用本身并非一个IM应用的话,这种方式成本极高。
现在的应用都趋向于使用心跳包来标识用户是否在线。用户登录后,每隔一段时间,往服务器推送一个消息,表示当前用户在线。服务器则可以定义一个时间差,例如:5分钟内收到过客户端心跳消息,视为在线用户。
在线用户统计的实现
基于数据库实现
最简单的办法,就是在用户表,添加一个最后心跳包的日期时间字段 last_active。服务器收到心跳后,每次都去更新这个字段为当前的最新时间。
如果要查询最近5分钟活跃的用户数量,就可以简单的通过一句SQL完成。SELECT COUNT(1) AS `online_user_count` FROM `user` WHERE `last_active` BETWEEN '2020-12-22 13:00:00' AND '020-12-22 13:05:00';
弊端也是显而易见,为了提高检索效率,不得不为last_active字段添加索引,而因为心跳的更新,会导致频繁的重新维护索引树,效率极其低下。
基于Redis实现
这是比较理想的一种实现方式了,Redis基于内存进行读写,性能自然比关系型数据库好得多,而且它所提供的Zset可以很方便的构建出一个在线用户的统计服务。
Redis的Zset
这里不会涉及太多redis的东西,简单说明以下zset。它是一个有序的set集合,集合中的每个元素由2个东