大战黑客,一路披荆斩棘,百亿互联网金融平台救火故事!(5)
百亿互金平台背后的关键事故 01、并发满标公司系统刚上线的时候,没有经历过什么大量用户并发的考验,结果公司做了一个大的推广,涌入了一批用户来抢标,共 1000 万的标的几乎都在 10秒之内搞定。 大概会有上万左右的用户会同时去抢标,平均每秒大概有千人左右的并发,满标控制这块没有经过大的并发测试,上来之后就被打垮了,导致的结果是什么呢? 1000 万的标的,有可能到一千零几万满标,也有可能会九百多万就满标,也就是要不就是多了一些,要不就是少了一些,就满标了。 这就会很尴尬,因为借款用户就借款一千万整,那么多出来的钱不能给用户回退,因为用户好不容易才抢上了,无端退了用户也闹。 少了也是问题,用户借款一千万,少了几十万也不行,如果缺的少了可以想办法找一些有钱的客户直接给买了,多了就必须重新放出来让用户投资,非常影响士气,这个问题困扰了我们有一段时间。 购买标的流程图,不知道大家是否能根据此图发现问题呢? 超募 为何会产生超募?在最早前的版本中没有使用乐观锁来控制,如果在最后购买的用户一单出现并发,就会出现超募。 比如最后剩余 30000 份的购买份额,因为并发量特别大,可能同时会有十几个用户拿到了剩余 30000 份余额的可购买额度,有的买 1000 份、有的买上3000 份、有的买上 20000 份都会驱动满标,所以最后导致了超募。 针对这个问题,我们主要是引入了 memcached 乐观锁的概念(底层主要是 cas、gets 两个命令),在发标的时候存入标的总份额。 当用户购买的时候首先去锁定用户购买的份额,因为乐观锁的原因,如果同时有两个用户拿到份额的时候保证只有一个最后可以更新成功(锁定份额),(锁定份额)失败直接返回,这样就保证了在入口的时候就直接屏蔽了部分并发的请求。 少募 为何产生少募?少募是可能 1000 万的标的突然到 980万就给满标了,这是因为在超募情况下我们完善了代码,用户一进来首先就是锁定购买份额,只有锁定购买份额才能进行下面的流程。 如果锁定购买份额失败直接返回,这样虽然保证了 1000 万份额在购买初期必须每一个用户只能锁定一份。 但是在高并发的情况下,因为购买流程中有十几个分支,每一个分支失败就会退回锁定的份额,这样就会导致这样的现象,就是可能是并发一上来,马上就满标了,过了一会进度又回退回来了。 少募主要是因为分支失败回退导致的,一方面我们分析了容易导致回退热点。因为在用户抢标的时候会给用户实时的展示标的进度,在很早的版本中直接就是存入到一个标的进度表里面,并且采用了乐观锁。 如果并发一高就频繁的更新失败导致回退,因此优化了标的进度这块,直接去掉了标的进度表,实时根据查询来展示标的进度(可以有延迟,有缓存)。 另一方面在回退份额的时候再次判断试下 memcached的份额和标的的状态,如果份额不为零并且标的状态是满标,马上自动更新状态保证后续用户可以立即购买再次驱动满标。 做了以上的两种优化后,我们还遇到了其他的一些小问题,在不断的优化过程中,终于稳定下来;在后期版本中将考虑使用 MQ 队列或者 redis队列来处理抢标,对用户也更合理更公平一些。 02、重复派息2015年的某一天看到一个新闻说是陆金所的一个用户发现自己银行里面突然多了很多钱,没过多久又被扣走了,然后收到陆金所那边的解释,说是给用户还本派息的时候,程序出现了问题导致还本派息两次。 当他们程序员发现了此问题后紧急进行了处理,用户当然闹了呀,然后就上了新闻,当然陆金所通道能力确实比较强可以直接从用户卡里面扣。 当大家都兴致勃勃的谈论这个话题的时候,我却有一股淡淡的忧伤,为什么呢?因为这个错误我们也犯过,具体说就是我搞的,大家不知道我当时的心理压力有多大! 事情是这样子的,我们使用的第三方支付的扣款接口不是特别的稳定,于是我们前期就对接了两种不通的扣款接口,平时前端投资的时候走一个接口,后端派息或者还本的时候走另外的一个接口。 在初期的时候扣款接口不稳定,因此在给用户跑批的时候经常会有个别用户失败,需要手动给失败的用户二次派息。 做为一个有志向的程序员当然觉得这种方式是低效的,于是将程序改造了一下,在后端派息的时候当第一种扣款失败的时候,自动再次调用第二种扣款接口进行扣款。 当时想着这种方式挺好的,各个环境测试也没有问题,上线之后监控过一段时间也运行稳定。 当我感觉一切都很美妙的时候,事故就来了,突然有一天客服反馈说有的用户说自己收到的利息感觉不对,好像是多了(真的是太感谢这个用户了),我登录后台看了一下派息的流水复核了一遍,果然利息被重复派了。 瞬间我感觉一股冷水从头而下,迅速把当天所有的用户派息记录和到期记录都进行了检查,还好只影响了 70 多个用户,导致多派息了 6 万多元。 幸亏只是派息出了问题,如果是到期的话金额会翻 N 倍,其中 70多个人里面有几个进行了体现、几个进行了再次投资,绝大部分用户在我们发现的时候还不知情,金额也没有动。 怎么处理呢?当然不能直接就动用户的钱了,给每个重复派息的用户打电话,说明原因赠送小礼物,请求谅解后我们把重复派过的利息再次调回来。 大部分用户进行了核对之后都还是比较配合的,但是肯定有一些用户不干了,当然也不能怪客户,都是我的原因,有的客户需要上门赔礼道歉,有的客户需要公司出具证明材料,我们的老板亲自给客户打了N 个电话被客户骂了 N 遍。 我心理压力可想而知,其中有一个客户特别难缠,各种威胁说既然到了我的账户里面肯定是我的,你们的失误不应该让他来承担,折腾了很久,还是不能怪客户。 可能会说有的互联网公司经常出现这种问题后就送给客户了,哎,我们是小公司呀!这个噱头玩不起。 到底是什么原因呢?事后进行了复盘也给领导做了汇报,平时都是首先进行派息的定时任务,过一个小时之后进行到期的定时任务。 (编辑:ASP站长网) |