可暂停加速器的计费逻辑/数据库设计疑问

281 天前
 sduoduo233

正在设计一个类似雷神/Golink 的加速器系统,没想好怎么实现暂停时长

目前的想法是有一个用户表记录剩余时长和是否暂停:

id int
...
paused bool
time_remain int

然后再开一个定时任务每五分钟把没有暂停的用户时间-5

求教各位老哥有没有更优雅的方法

5509 次点击
所在节点    程序员
27 条回复
IlllIlllIlIIl
280 天前
@IlllIlllIlIIl #20 再补充一点,不能允许让用户在暂停状态下充值,
listen2wind
280 天前
@leaflxh 求告知 2038 是什么问题
yidinghe
280 天前
这个设计的核心要素是用户的每次使用时段,所以必须设计一个使用时段表。使用时段表需要详细记录用户每次的使用时段,当用户有疑问时,你要拿这些记录出来进行核对。

使用时段表包含下面的主要属性:用户 ID 、开始时间、计费权重(如果有的话)、结束时间(为空表示正在计费中)、时长(结束时间为空时这个字段也为空)

开始计时:使用时段表新增一条记录,记录用户 ID 和开始时间。

结束计时:在使用时段表中找到未结束的记录,填入当前时间作为结束时间,以及时长。

如何实时计算用户的使用时长:选取所有已结束的记录,用 union all 拼接上那条未结束的记录(其时长为当前时间减去开始时间),然后对时长求和即可。

如果你不想扫描太多记录,那么可以给用户添加冗余字段:每次结束计时后,将所有已结束的记录合计一下,存入用户表。那么实时计算用户的使用时长,就只要从用户表取一条用户记录,再从使用时段表取一条或零条未结束记录即可。
yidinghe
280 天前
@yidinghe 计算用户使用时长可以简化,不用 union all ,下面是一个例子:

select
sum(
case
when end_time is null then TIMESTAMPDIFF(SECOND, start_time, now())
else then TIMESTAMPDIFF(SECOND, start_time, end_time)
end
) as duration
from acc_records
where user_id=?
Terminl
280 天前
我思考了一下,一楼方案可以改一改采纳。在用户点击暂停时,将用户状态修改为暂停,服务端对有效期结算并备份上一次暂停的有效期后下发给客户端暂停时间计数指令。下一次点击恢复的时候读取最新的有效期,如此循环即可。
Terminl
280 天前
还有一个是服务端过滤低于多少秒的账户进入心跳检测,账户时间为 0 时强行断开连接。
sduoduo233
280 天前
感谢各位老哥的回复

看了一下感觉 1 楼的方法是最简单的,总结一下就是这几个 SQL

CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
time_left INTEGER DEFAULT(0), 剩余时长 单位是秒
paused INTEGER,
resume_time INTEGER 上一次恢复计时的时间戳
)

剩余 60 秒的时长
INSERT INTO users (time_left, paused, resume_time) VALUES (60, TRUE, 0)

恢复
UPDATE users SET paused = FALSE, resume_time = unixepoch() WHERE id = 1

暂停
UPDATE users SET paused = TRUE, time_left = time_left - (unixepoch() - resume_time) WHERE id = 1

定时任务 更新未暂停用户的剩余时间
UPDATE users SET time_left = time_left - (unixepoch() - resume_time), resume_time = unixepoch() WHERE paused = FALSE

9 楼的应该也是差不多的思路

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1015307

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX