计费系统的 金额结算怎么做?

2020-12-05 10:14:16 +08:00
 kikione

单应用,单数据库

业务是这样的: 用户请求我们 API 查询,先在账户充值金额。

每请求一次 API 会有一次计费,请求成功计费,余额减; 失败不计费; 余额不足请求失败;

余额结算怎么做比较好?业界都是什么方案?

2503 次点击
所在节点    程序员
13 条回复
securityCoding
2020-12-05 10:17:52 +08:00
请求前检查费用(商户锁) -》请求成功-》消息队列-》扣费
securityCoding
2020-12-05 10:18:23 +08:00
没有消息队列可以使用 redis stream
moult
2020-12-05 10:31:56 +08:00
请求 API 肯定有写记录吧。根据请求记录表,十分钟或一小时统一扣费一次。云服务那些按量计费很多都是一小时甚至一天计费在。实时扣费的话真的太浪费资源了。
kikione
2020-12-05 11:14:13 +08:00
@moult 谢谢
kikione
2020-12-05 11:14:19 +08:00
wangbenjun5
2020-12-05 11:47:59 +08:00
像这种单应用单数据库太简单了,一个锁就解决了并发问题,保证 1 毛钱不亏
wangbenjun5
2020-12-05 11:50:57 +08:00
当然如果考虑到锁的性能影响接口速度的话就不要使用数据库锁,可以使用内存锁,redis 锁。如果使用队列做成异步模式的话可能会导致超额,假设并发量大的话。
kikione
2020-12-05 12:15:29 +08:00
@wangbenjun5 给数据库加一个 乐观锁就可了是吧
kingwrcy
2020-12-05 12:16:32 +08:00
金额弄成 可用余额 ,冻结金额.

余额是否足够判断,用 可用金额 来判断.

每一次调用 api,冻结金额 增加,可用金额 减少.
调用 api 成功,冻结金额 减少,可用金额 不变.
调用 api 失败,冻结金额 减少,可用金额 增加.

然后按天对账,及时发现有问题的数据.

另外变更金额一定得用乐观锁.
Dabaicong
2020-12-05 12:48:46 +08:00
如果实时计费,最好是悲观锁。select for update 。记得 where 条件中要有索引,要不然就会退化成表锁
brucefu
2020-12-05 13:01:17 +08:00
如何定义“请求一次”,为请求一次做一个唯一键,异步插表就好,要保成功。将来计费系统单独出去的话,就发消息出去
dengkj
2020-12-05 21:28:10 +08:00
MySQL RR RC 级别的话不用显式加锁,只需要判断用户余额是否大于等于零即可,数据库会自动加锁
kikione
2020-12-15 16:02:27 +08:00
@dengkj 感谢

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

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

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

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

© 2021 V2EX