首页 > 数据库 >Redis - 实现在线人数统计功能

Redis - 实现在线人数统计功能

时间:2024-06-02 23:33:31浏览次数:26  
标签:在线 Redis 用户 有序 集合 inf now 人数

一、前言

在线人数统计这个功能实现的方式很多,这里说一下常使用的方式:使用Redis的有序集合(zset)实现

核心方法是这四个:zadd、zrangeByScore、zremrangeByScore、zrem。

二、实现步骤

1. 如何认定用户是否在线?

认定用户在线的条件一般跟网站有关,如果网站需要登录才能进入,那么这种网站就是根据用户的token令牌有效性判断是否在线;

如果网站是公开的,是那种不需要登录就可以浏览的,那么这种网站一般就需要自定一个规则来识别用户,也有很多方式实现如IP、deviceId、浏览器指纹,推荐使用浏览器指纹的方式实现。

浏览器指纹可能包括以下信息的组合:用户代理字符串 (User-Agent string)、HTTP请求头信息、屏幕分辨率和颜色深度、时区和语言设置、浏览器插件详情等。现成的JavaScript库,比如 FingerprintJS 或 ClientJS,可以帮助简化这个过程,因为它们已经实现了收集上述信息并生成唯一标识的算法。

使用起来也很简单,如下:

// 安装:npm install @fingerprintjs/fingerprintjs

// 使用示例:
import FingerprintJS from '@fingerprintjs/fingerprintjs';

// 初始化指纹JS Library
FingerprintJS.load().then(fp => {
  // 获取访客ID
  fp.get().then(result => {
    const visitorId = result.visitorId;
    console.log(visitorId);
  });
});

这样就可以获取一个访问公开网站的用户的唯一ID了,当用户访问网站的时候,将这个ID放到访问链接的Cookie或者header中传到后台,后端服务根据这个ID标示用户。

2. zadd命令添加在线用户

1)zadd命令介绍

zadd命令有三个参数

  • key:有序集合的名称。
  • score1、score2 等:分数值,可以是整数值或双精度浮点数。
  • member1、member2 等:要添加到有序集合的成员。

例子:向名为 myzset 的有序集合中添加一个成员:ZADD myzset 1 "one"

2)添加在线用户标识到有序集合中

// expireTime给用户令牌设置了一个过期时间
LocalDateTime expireTime = LocalDateTime.now().plusSeconds(expireTimeout);
String expireTimeStr = DateUtil.formatFullTime(expireTime);
// 添加用户token到有序集合中
redisService.zadd("user.active", Double.parseDouble(expireTimeStr), userToken);

由于一个用户可能户会重复登录,这就导致userToken也会重复,但为了不重复计算这个用户的访问次数,zadd命令的第二个参数很好的解决了这个问题。

我这里的逻辑是:每次添加一个在线用户时,利用当前时间加上过期时间计算出一个分数,可以有效保证当前用户只会存在一个最新的登录态。

3. zrangeByScore命令查询在线人数

1)zrangeByScore命令介绍

  • key:指定的有序集合的名字。
  • min 和 max:定义了查询的分数范围,也可以是 -inf 和 +inf(分别表示“负无穷大”和“正无穷大”)。

例子:查询分数在 1 到 3之间的所有成员:ZRANGEBYSCORE myzset 1 3

2)查询当前所有的在线用户

// 获取当前的日期
String now = DateUtil.formatFullTime(LocalDateTime.now());
// 查询当前日期到"+inf"之间所有的用户
Set<String> userOnlineStringSet = redisService.zrangeByScore("user.active", now, "+inf");

利用zrangeByScore方法可以查询这个有序集合指定范围内的用户,这个userOnlineStringSet也就是在线用户集,它的size就是在线人数了。

4. zremrangeByScore命令定时清除在线用户

1)zremrangeByScore命令介绍

  • key:指定的有序集合的名字。
  • min 和 max:定义了查询的分数范围,也可以是 -inf 和 +inf(分别表示“负无穷大”和“正无穷大”)。

例子:删除分数在 1 到 3之间的所有成员:ZREMRANGEBYSCORE myzset 1 3

2)定时清除在线用户

// 获取当前的日期
String now = DateUtil.formatFullTime(LocalDateTime.now());
// 清除当前日期到"-inf"之间所有的用户
redisService.zremrangeByScore(""user.active"","-inf", now);      

由于有序集合不会自动清理下线的用户,所以这里我们需要写一个定时任务去定时删除下线的用户。

5. zrem命令用户退出登录时删除成员

1)zrem命令介绍

  • key:指定的有序集合的名字。
  • members:需要删除的成员

例子:删除名为xxx的成员:ZREM myzset "xxx"

2)定时清除在线用户

// 删除名为xxx的成员
redisService.zrem("user.active", "xxx");   

删除 zset中的记录,确保主动退出的用户下线。

三、总结

  这种方案的核心逻辑就是,创建一个在线用户身份集合为key,利用用户身份为member,利用过期时间为score,然后对这个集合进行增删改查,实现起来还是比较巧妙和简单。

标签:在线,Redis,用户,有序,集合,inf,now,人数
From: https://www.cnblogs.com/beatle-go/p/18209985

相关文章

  • Redis-目录
    背景:今天是2024.6.2。我在网上搂了500页redis相关的面试题,通过ai整理的提纲。为了方便复习,特此记录,逐章节更新。标题下方有链接的,就是更新好了。Redis基础Redis-Redis为什么快、底层数据结构Redis简介数据类型:String、List、Hash、Set、SortedSet常用命令过期时间设置......
  • Redis5学习笔记之四:高级特性(持久化、订阅、主从复制、缓存穿透和雪崩)
    4.redis高级特性4.1持久化Redis的数据全部在内存里,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证Redis的数据不会因为故障而丢失,这种机制就是Redis的持久化机制。Redis有两种持久化的方式:快照(RDB文件)和追加式文件(AOF文件)4.1.1RDB在指定的时间间隔内将内......
  • Redis
    Redis(RemoteDictionaryServer),即远程字典服务,是一个开源的使用ANSIC语言编写的、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis的数据结构丰富,支持存储的value类型包括string(字符串)、list(链表)、set(集合)、zset(sortedset--有序集合)和h......
  • Redis设计与实现(一)SDS与C字符串的对比
    sds的定义:每个sds.h/sdshdr结构表示一个SDS值:struct__attribute__((__packed__))sdshdr8{uint8_tlen;/*used*/uint8_talloc;/*excludingtheheaderandnullterminator*/unsignedcharflags;/*3lsboftype,5unusedbits*/char......
  • Redis单线程
    Redis是基于Reactor模式开发的网络事件处理器,这个处理器是单线程的,所以redis是单线程的。为什么它是单线程还那么快呢?主要有以下几个原因:一、纯内存操作由于Redis是纯内存操作,相比于磁盘来说,内存就快得多,这个是Redis快的主要原因。二、多路复用I/O机制(NIO)Re......
  • Linux系统上配置redis开机自启
    Redis开机自启:第一步添加环境变量:命令:vim/etc/profile在结尾添加:exportPATH=$PATH:/usr/local/redis/bin作用是为了后续脚本的启动命令不需写的过长重载环境变量文件:source/etc/profile第二步:编写redis.service节点1:152服务器vim/etc/systemd/system/redis.service添......
  • Redis的分布式缓存问题
    击穿  Redis曾存在的key,由于过期时间而被删除,导致请求跳过redis而访问DB处理方法:不设置过期时间,永远存在使用锁,synchronized、分布式锁布隆过滤器穿透  数据库与redis都不存在的key,由于莫名原因存在大量请求,导致请求跳过redis而访问DB处理方法:数据库不存在,redis也......
  • Redis 高级应用与性能优化
    目录1.Redis集群与高可用性Redis集群介绍高可用性方案与实践2.Redis性能优化与监控性能指标与监控工具Redis的性能优化策略实时监控与故障排查3.Redis实践场景与最佳实践缓存与缓存雪崩、击穿、穿透计数器和限流器的实现分布式锁的应用实际项目中的Redis......
  • APM2.8用USB在线下载固件
    1.把APM飞控用安卓手机的USB线插入电脑。选择COM口,不要选择auto,如果你没有COM口说明你驱动安装有问题。波特率115200。点击相应的图标就可以下载固件到飞控板。请注意:烧录APM必须选择INSTALLFIRMWARELEAGACY,第一个是用于刷pixhawk的,不适合APM,烧录APM必须选择第二......
  • 适合技术小白学习的项目1863java在线视频网站系统 Myeclipse开发mysql数据库web结构ja
    一、源码特点java在线视频网站系统是一套完善的web设计系统,对理解JSPjava编程开发语言有帮助采用了java设计,系统具有完整的源代码和数据库,系统采用web模式,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql,使用java语言开发。java在线视频......