如何统计网站的在线人数呢?java
首先很简单的思想就是,若是只针对会员用户进行统计,在登陆登出时加判断,而后维护一个表(或者其余存储方式)来存储在线会员便可。redis
可是有个问题就是,对于正常退出的会员固然可使用这种方式,那若是该会员是关闭了网页或者停电或者其余因素,那如何得知这些状况呢?数据库
假设使用数据库来完成这个功能,想要达到最快的速度,就直接使用MYSQL内存表来保存在线会员的记录,
1:当会员登陆时(包含自动登陆),便去查找该会员是否存在于内存表当中,若是存在,则更新在线表当中的时间,若是不存在,则插入相应数据到内存表当中去
2:在用户退出时,因为没有进行办法实时的更新,由于用户有可能直接关闭网页离开,只能根据时间段来解决这个问题,写一个计划任务,每隔半个小时(或者其余时间),执行一次该程序,该程序主要的做用是扫描当前在线表当中,更新时间是否有小于当前时间10分钟或者多少分钟(这个根据具体状况自定义)的,若是有,则直接删除该条记录,这样便保证了大概的在线人数的统计。服务器
这种作法的缺点,当用户数量很大时,对数据库压力会很大。session
将第一种方案的数据库改为使用redis,可以减轻数据库的负担,读写也更快。性能
固然咱们能够从另外一个角度来看,若是要统计的不单单是会员,要统计来访问网站的在线人数,咱们能够考虑保存session(详情请查看服务器集群session共享),当session过时时则删除记录,相比于第一种方案,这种方案准确率就低了不少,可是性能更好。网站
这里要提到的另外一种思考是,如何统计网站的活跃用户呢?(好比把天天都登陆称为活跃用户)spa
假设某网站有1亿用户,就算平均天天登陆3000W用户,这个数据天天也至关庞大。.net
这里可使用bitmap来保存用户登陆情况,由于是否登陆其实就是0/1,因此只用一位来保存就够了。这样存储就大大下降了。code
咱们把天天的用户登陆信息记录到一个key中,值中的每一个offset的值就是用户登陆的标识
(1)设置关键字的指定offset的值为 0 或 1
setbit key 100 1
(2)bit运算
例如
key1 -> 0101
key2 -> 0011
and 运算
bitop and ret key1 key2
就是对 key1 key2 各位进行 and 运算后赋值给 ret,结果为 0001
or 运算
bitop or ret key1 key2
就是对 key1 key2 各位进行 or 运算后赋值给 ret,结果为 0111
(3)bit值为1的数量
bitcount key
经过bit操做就能够实现用户统计的需求了
例现在天为 2016-05-28
把 key 定义为 userlogin:20160528
(1)用户登陆
ID为 100 的用户登陆了,执行
setbit userlogin:20160118 100 1
(2)统计今天登陆的用户数
bitcount userlogin:20160118
(3)统计3天内都登陆过的用户
“都登陆过”是要取得bit值都为1的,经过 and 计算获取
bitop or ret userlogin:20160116 userlogin:20160117 userlogin:20160118
(4)统计7天内登陆过的用户
“登陆过”表示bit值有一个为 1 便可,因此经过 or 计算获取
命令与上一个相似
1. http://bbs.csdn.net/topics/330154127
2. http://blog.edagarli.com/2016/01/20/%E4%BD%BF%E7%94%A8Redis%E7%BB%9F%E8%AE%A1%E6%B4%BB%E8%B7%83%E7%94%A8%E6%88%B7/