百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

面试官:如何统计在线人数(怎么在线统计信息)

mhr18 2025-04-06 18:53 23 浏览 0 评论

昨天,一位朋友在面试中被问到:如何统计在线人数?

估计有的朋友做过这个功能,但有没有想过方案是否可以在优化。没有了解过的朋友,那就趁机学习一下,防止下次面试自己被遇到。

免费使用刷题网站!

在线人数统计这个功能相信大家一眼就明白是啥,这个功能不难做,实现的方式也很多,这里说一下我常使用的方式:使用Redis的有序集合(zset)实现。

核心方法是这四个:zaddzrangeByScorezremrangeByScorezrem

实现步骤

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

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

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

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

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

// 安装: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 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,然后对这个集合进行增删改查,实现起来还是比较巧妙和简单的,大家有兴趣可以试试看。

相关推荐

【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...

Pure Storage推出统一数据管理云平台及新闪存阵列

PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...

对Java学习的10条建议(对java课程的建议)

不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...

SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!

官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...

JDK21有没有什么稳定、简单又强势的特性?

佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...

「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了

在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...

Java面试题及答案最全总结(2025版)

大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...

数据库日常运维工作内容(数据库日常运维 工作内容)

#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...

分布式之系统底层原理(上)(底层分布式技术)

作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...

oracle 死锁了怎么办?kill 进程 直接上干货

1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...

SpringBoot 各种分页查询方式详解(全网最全)

一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...

《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略

《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...

LoadRunner(loadrunner录制不到脚本)

一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...

Redis数据类型介绍(redis 数据类型)

介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...

RMAN备份监控及优化总结(rman备份原理)

今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...

取消回复欢迎 发表评论: