前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于Redis Zset实现在线用户统计

基于Redis Zset实现在线用户统计

作者头像
Diuut
发布2022-11-22 20:24:21
6850
发布2022-11-22 20:24:21
举报
文章被收录于专栏:Diuut

需求: 统计页面的当前在线用户统计。

由于不是socket连接,所以不是真实的实时在线用户,是对用户登录或者普通操作的时间进行标记时间戳,时间戳之后多少分钟内,都是算作在线的,限定时间之后就算作离线。

在我当前项目中我有一个统一的token验证方法,我就把标记时间戳的方法加在该方法中。

代码语言:javascript
复制
 /**
     * 在线用户统计
     * @param uid uid
     */
//用户在线时间戳
    private void onlineUser(int uid) {
        redisTemplate.opsForZSet().add("onlineUserCount", uid + "", ServerTimer.getDayHourMinute());
    }

    /**
     * 公共登陆验证
     *
     * @param name  用户名
     * @param token token
     * @return result
     */
    private String CommonLogin(String name, String token) {
        User user1 = userRedisDao.getOneByName(name);
        if (user1 == null) {
            return "用户" + name + "不存在";
        }
        User user = userRedisDao.getOneByToken(token);
        if (user == null) {
            return "登陆过期,请重新登陆";
        }
        if (user.getUid() != user1.getUid()) {
            return "已在其他设备登陆,请退出应用重新登陆";
        }
        this.onlineUser(user.getUid());
        return "success";
    }

这里的ServerTimer.getHourMinute()是将当前时间存为HHmm的一个int,作为时间戳存入“onlineUserCount”这个key的一个member的分数中,用于之后自动判断过期清除。

代码语言:javascript
复制
	//ServerTimer.getHourMinute()
	public static int getDayHourMinute() {
		String timeHm = ServerTimer.getTimeHm();
		return Integer.parseInt(timeHm);
	}
        public static String getTimedHm() {
		Calendar now = Calendar.getInstance();
		SimpleDateFormat s = new SimpleDateFormat("ddHHmm");
		return s.format(now.getTime());
	}

存入时间戳的步骤就到这里,之后我们还需要一个定时任务用于自动清除过期的member:

代码语言:javascript
复制
    //5分钟未操作清除用户在线统计
    @Scheduled(fixedDelay = 60000)
    public void clearOnlineUser() {
        Calendar now = Calendar.getInstance();
        now.add(Calendar.MINUTE,-5);
        SimpleDateFormat s = new SimpleDateFormat("ddHHmm");
        int score = Integer.parseInt(s.format(now.getTime()));
        Long count = redisTemplate.opsForZSet().removeRangeByScore("onlineUserCount", -1, score);
        log.info("当前在线用户:{}",count);
    }

查询方法:

代码语言:javascript
复制
    /**
     * 获取当前在线用户数
     *
     * @return 当前在线用户数
     */
    public Object getOnlineUser() {
        return redisTemplate.opsForZSet().count("onlineUserCount", -1, 999999);
    }

以上就是基于redis Zset在线用户的解决方案,相较于心跳,减少了与前端的交互,纯后端实现, 且内存占用性能占用均在可接受的范围内。

Post Views: 233

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020年10月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档