redis统计APP在线人数的实例
作者:宛十八 发布时间:2023-11-24 23:56:54
最近有个需求,需要统计APP的在线人数,其实以前也统计过,采取的是上线发送一个请求$this->cache->incr()加1,下线的时候$this->cache->decr()减1,可是这样做的后果是,发现在线人数错的离谱,几千人同是在线。
why?原来APP端如果卸载的时候,那么就不会发请求,还有如果非正常终止的时候,也不会发送下线请求?
于是乎找一个准备的统计方式
1:客户端十分钟发送一次请求,带上序列号,服务器端set('前缀.序列号',过期时间),然后服务器端统计 keys 前缀*
可是你看keys之后的数据格式:
var_dump();
array (size=2)
0 => string 'c_001dddddddddddddddddddddddddddddddd' (length=37)
1 => string 'c_001ddddddddddddddddddddddddddddddddd' (length=38)
print_r();
Array( [0] => c_001dddddddddddddddddddddddddddddddd [1] => c_001ddddddddddddddddddddddddddddddddd)
数据keys *之后数据格式乱糟糟的,不是数组,根本没有办法处理。也许可以把他看成一个文件,然后正则匹配,再出处理,可是这样有多慢呢,keys *本来就有些慢,还存入文件,正则匹配,然后循环,获取数组长度,就更加慢了。
keys *之后出来是列表吧,更本不是数字,redis也没有这种获取某个特殊的键前缀的数量的函数。
如果APP就一个的话,大家可以把这个键值存储到一个库里面,然后用dbsize()直接获取库数量,这个库不存储其他的键值。
可是现在我要统计六个APP的在线情况,不可能一个APP存储一个库吧
2:利用序列,
$date = date("Ymdh",time()); $this->_cache->sadd($date.$head,$client,7200);
获取当前时间,之后加上客户端类型前缀,作为键,存入序列,本次方法是一个小时存取一次,就是一个小时之内的都算在线人数,具体多久算在线人数,大家可以自我把握。
存的时候:
$date = date("Ymdh",time());
$this->_cache->sadd($date.$head,$client,7200);//存入集合 1个小时存入一次
取数量的时候
$date = date("Ymdh",time());//当前时间
$hour = date("Ymdh",time()-3600);//上一个小时时间
$score = date("i",time());//当前时间分数
$datedata= $this->_cache->scard($date.$head);//这个小时数量
$hourdata= $this->_cache->scard($hour.$head);//上个小时数量
if($score == '00'){
$online = $hourdata;//如果当前时间是整点,那么一个小时人数,就是上个小时人数
}else{
$online = intval(((60-$score)/60)*$hourdata)+ $datedata;//如果不是整点,那么计算当前多少分钟,当前的数量,加上上个小时比例数量 凑够一个小时数量
}
$online就是在线数量
补充知识:redis命中率计算
redis提供了INFO这个命令,能够随时监控服务器的状态,只用telnet到对应服务器的端口,执行命令即可:
telnet localhost 6379
info
在输出的信息里面有这几项和缓存的状态比较有关系:
keyspace_hits:14414110
keyspace_misses:3228654
used_memory:433264648
expired_keys:1333536
evicted_keys:1547380
通过计算hits和miss,我们可以得到缓存的命中率:14414110 / (14414110 + 3228654) = 81% ,一个缓存失效机制,和过期时间设计良好的系统,命中率可以做到95%以上
有个ruby gem叫redis-stat,它利用INFO命令展现出更直观的信息报表,推荐:
https://github.com/junegunn/redis-stat
来源:https://blog.csdn.net/kdchxue/article/details/51023183


猜你喜欢
- 1、本篇内容本文让大家掌握 springmvc 中异步处理请求,特别牛逼的一个功能,大家一定要掌握。2、看段代码,分析问题@Response
- 一、项目创建创建一个控制台应用程序,项目右键->管理 NuGet 程序包->Topshelft及Topshelf.Log4Net
- 本文实例为大家分享了C#窗体实现酒店管理系统的具体代码,供大家参考,具体内容如下一、概述酒店管理系统是我们常说的MIS (Managemen
- 如果我们只是需要让用户能够拍摄照片,则可以直接请求已有相机应用拍摄照片并将照片返回给我们1、拍照1.1 请求相机功能在清单文件中添加: &n
- 一般使用@RequestBody接收的时候报400都是传入的json字符串和对应封装的对象不对应造成的首先要注意封装的对象中的字段类型有没有
- 关键字 static1. 概述static 是一种修饰符static 是Java中表静态的关键字它可以修饰成员变量、成员方法、代码块被sta
- 在一次Java解析xml文件的开发过程中,使用SAX解析时,出现了这样一个异常信息:Error on line 60 of document
- 接着上篇文章,我们继续来学习 Java 中的字节流操作。装饰者缓冲流 BufferedInput/OutputStream装饰者流其实是基于
- 本文为大家分享Android自定义Spinner适配器的相关知识点,供大家参考,具体内容如下一、大致效果二.关键代码在注释中讲重点吧。 (1
- 本文实例为大家分享了Android仿京东左侧分类条目效果的具体代码,供大家参考,具体内容如下import android.app.Activ
- 在SSH项目中,有时需要由一个Action跳转到另一个Action。有两种方式可以实现Action之间的跳转,一种是chain,另一种是re
- 1、springboot controller 单例Spring中 controller默认是单例的,因为单例所以不是线程安全的。所以需要注
- 本文实例讲述了Java使用TCP套接字实现多人聊天功能。分享给大家供大家参考,具体如下:废话不多说,直接开搞:先创建一个服务端:packag
- 大家好,今天我和大家分享一下用Java编写日历表,我用了3种方式实现这一功能的。首先我们来看看一个日历表有什么特征。在这里我就把我电脑上的日
- 由C#转入Java一段时间了,总结下个人认为的Java同C#语法之间的不同之处,有不同意见之处还望各位海涵 刚学Java时觉得语法同C#大致
- @RequestMapping和@GetMapping @PostMapping的区别最近学习看一些代码,发现对于发送请求这件事,有的地方用
- 作为java中的一个重要理念,说起面向对象也是老生常谈了。在找资料的时候多是很专业的术语,又或者很多框架的知识点合集,其实大部分人刚看资料的
- 本文实例为大家分享了Unity实现本地文本多语言化的具体代码,供大家参考,具体内容如下在unity项目过程中大多都会遇到多语言化,下面讲一下
- 考虑一个场景,轮流打印0-100以内的技术和偶数。通过使用 synchronize 的 wait,notify机制就可以实现,核心思路如下:
- 定义里氏替换原则(Liskov Substitution Principle,LSP),官方定义如下: 如果对每一个类型为S的对象o1,都有