V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
npe
V2EX  ›  问与答

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

  •  
  •   npe · 2019-06-26 21:56:43 +08:00 via Android · 1815 次点击
    这是一个创建于 1977 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    业务逻辑大概是:

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

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

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

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

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

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

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

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

    如果 qps 达不到要求还要减少 io。可以以 redis 数据为准,则还可以减少用户流水的记录(存在优惠券丢失的情况,更新 redis 成功,写 mysql 失败。需要业务逻辑去补充这类数据)。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2500 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:31 · PVG 23:31 · LAX 07:31 · JFK 10:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.