请教一个高并发竞争资源问题

2019-06-26 21:56:43 +08:00
 npe

有个 coupon-service (优惠券服务)部署在 N 台机器上,该服务提供一个抢券接口对外使用。

业务逻辑大概是:

1.用户随机从优惠券表拿一条数据(查询)

2.将数据插入到用户优惠券表(更新)

3.删除优惠券表的该优惠券(删除)

现在该接口预估峰值并发请求在 5K~10K 左右,怎样在高并发情况下保证服务的可靠性和数据的一致性?目前想到的是,将所有优惠券放入 activeMQ,每个领券请求去 MQ 中 POP 数据,但是如果出现异常情况该如何回滚数据? 求大家谈谈经验。。。

1820 次点击
所在节点    问与答
6 条回复
billlee
2019-06-26 23:56:20 +08:00
要不换个思路,把抢券请求放 mq, 然后服务根据 mq 异步发券。
npe
2019-06-27 07:49:16 +08:00
293 次点击,1 条回复,这是技术论坛吗。。
mejee
2019-06-27 08:07:19 +08:00
先查再删的话应该会多个线程查到同一个记录吧? MQ 是个选择,但是好像只能按照顺序拿,不能随机拿吧。可以换个思路,往 MQ 放数据的时候可以按照随机的顺序放。至于异常情况的处理,一般 MQ 有恢复机制吧
ikaros
2019-06-27 09:14:18 +08:00
按照你这个思路出了异常把优惠券再 push 进 MQ 还回去咯

另外有个方法就是有一个中心调度优惠券的服务把数量下发到每个服务器咯,当下面服务器库存不够再请求调度服务器这样?
npe
2019-06-27 09:59:34 +08:00
@mejee 对,这就是并发会出现的问题,所以选择使用 MQ 来做同步消费。关于 MQ 的异常恢复我再研究研究。。
luw2007
2019-06-27 13:59:24 +08:00
优惠券不会比 12306 复杂。 优惠券提前生成,乱序放到 redis 的列表里面,或者 MQ 里面。

redis 列表可以按照用户 hash,这样可以减少一次锁。并且可以拆分到多个 redis 中,增加 qps ( 1w qps 用不到)。
拿到优惠券之后,就同步记录用户流水,并更新优惠券状态。 如果更新成功再记录流水。

如果需要同步快速返回,可以将更新优惠券状态改成异步处理,但是到账也是异步。

如果 qps 达不到要求还要减少 io。可以以 redis 数据为准,则还可以减少用户流水的记录(存在优惠券丢失的情况,更新 redis 成功,写 mysql 失败。需要业务逻辑去补充这类数据)。

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

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

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

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

© 2021 V2EX