惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google DeepMind News
Google DeepMind News
T
Tenable Blog
博客园_首页
S
Securelist
Spread Privacy
Spread Privacy
Google Online Security Blog
Google Online Security Blog
Forbes - Security
Forbes - Security
Engineering at Meta
Engineering at Meta
U
Unit 42
L
LINUX DO - 热门话题
量子位
T
Threat Research - Cisco Blogs
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
K
Kaspersky official blog
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
The Last Watchdog
The Last Watchdog
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
Martin Fowler
Martin Fowler
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Security Latest
Security Latest
Scott Helme
Scott Helme
V
Vulnerabilities – Threatpost
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
Know Your Adversary
Know Your Adversary
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
T
The Blog of Author Tim Ferriss
aimingoo的专栏
aimingoo的专栏
V2EX - 技术
V2EX - 技术
T
Tailwind CSS Blog
月光博客
月光博客
Recent Announcements
Recent Announcements
G
Google Developers Blog
F
Full Disclosure
W
WeLiveSecurity
宝玉的分享
宝玉的分享
腾讯CDC
G
GRAHAM CLULEY
Vercel News
Vercel News
Simon Willison's Weblog
Simon Willison's Weblog
美团技术团队
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security

星辰日记

临时邮箱:开发者的隐私工具实践笔记 为 QuMagie 备份的照片添加 Exif 信息 Riverpod - flutter 状态管理的应用 夜景随拍 大疆 Mini 4K 初体验 5月12日 随笔 你好 2024 HHKB 使用体验 历经59天, 终于拿到软著 渺软公益CDN - 又一个静态资源加速站 你好 2023 记一次 RAID 硬盘离线 大一 碎语 试用 Google CA 的 SSL 证书 Waline 邮件异步推送 Magic Trackpad 使用体验 Centos 编译安装 php81 Centos 7 升级 Glibc-2.28 Nginx 重写 Query 参数
Redis 统计实时在线人数
xcsoft · 2022-06-06 · via 星辰日记

zset

Redis 中的 sorted set (有序集合) 也称为 zset. 它提供了两个参数, 一个为 score, 一个为 member.

其中, score 为排序的分数, 它可以是双精度或者整数. 其结构类似

1
2
3
        | (score) member1
key => | (score) member2
| (score) member3

如何实现

我们可以简单的通过 zadd 方法向一个有序集合内添加成员.

为了方便演示, 在这里使用 Interval 的方式, 定时请求指定接口. 将 score 设置为请求时的 unix时间戳

zset 提供了一个 zcount 方法, 可以让我们快速获取指定 socre 范围内的成员数量.

我们假设用户5秒钟内无操作, 即掉线. 这样便可以通过 zcount 获取实时在线人数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func main() {

r := gin.Default()

r.GET("/", func(c *gin.Context) {
_redis := redisutil.R.Get()
defer redis.Close()


userId := c.ClientIp()
_, _ = _redis.Do("ZADD", "online_user", time.Now().Unix(), userId)


count, _ := redis.Int(_redis.Do("ZCOUNT", "online_user", time.Now().Unix()-5, "+inf"))

c.JSON(200, gin.H{
"count": count,
})
})

r.Run()
}

当然, 为了防止 数据一直增加, 对于 5秒前的数据, 应该定时将其移出.

我们可以通过 zremrangebyscore 方法, 来移除 指定范围内的数据.

1
2
3
4
5
6
7
8
9
10
11
func AutoRemover() {
_redis := redisutil.R.Get()
defer redis.Close()

c := Cron.New()

c.AddFunc("@every 5s", func() {
_, _ = _redis.Do("ZREMRANGEBYSCORE", "online_user", "-inf", time.Now().Unix()-5)
})
c.Start()
}

zset 的其他方法

除了上述提到的方法, zset 还提供了很多其他的方法, 如:

  • zcard key 直接获取 指定 key 内的成员数量
  • zscore key member 获取指定成员的分数
  • zincrby key incr member 增加指定成员的分数
  • zrange key start end [WITHSCORES] 获取指定范围内的成员 并按照分数从小到大排序
  • zrevrange key start end [WITHSCORES] 与上一个相反
  • etc.

其他

可以在 Github 找到 示例.

这里同时实现了, 所有用户及自己的 在线时间显示.

当然, 也可以通过 WebSocket 来实现类似的功能, 这样会更加准确, 但是可能会带来一定的性能损失.

参考