广告业务Bug复盘总结

因为公司业务调整,最近接手了公司的广告系统的业务,其中遇到这样的一个Bug,它的表象是这样:广告主账户里面没钱了,但是广告依然给他投放了出来


一、基本业务逻辑

首先广告的计费方式有几种,CPA,CPT,CPC,CPM等,而CPM这种计费方式是按每1000次曝光收费x元,也就说如果单价为10元,那么单次曝光就是0.01元,每次曝光我们首先都会从广告系统的缓存余额里面扣对应的钱,扣完钱,会给账户系统发送一条事物消息,然后执行本地事物,将扣款订单落库,事物提交,然后账户系统那边也会在缓存里面记录扣款金额,如果账户那边扣款失败,也会发送一条扣款失败的消息,广告系统收到此消息后,会将余额补回进自己的缓存里面。
 

这里有个不太理解的点:

为什么广告这边都已经曝光出去了,但是调用账户系统扣款失败,就要把用户的余额给补回去,好比商户都把商品卖出去了,但是用户支付的时候扣钱扣失败了,就又给用户把余额补回去了。


二、Bug点

bug就在扣款失败,补回用户余额这里,因在再给账户系统发送CPM一类广告消息的时候,会将精度提升3,也就是单个曝光金额会 * 1000 发送给账户系统,而账户系统在扣款失败的时候,原封不动的将 * 1000过后的单价发送过来,并补回广告系统的用户余额里面。这里我举个例子:

假设用户余额1000,单个曝光2元(贵了哈~),单次曝光之后,用户余额应该是998元,但是账户系统扣款失败,会将用户余额补回,由于 * 1000,提升3精度,补回的余额就变成了 998 + 2 * 1000 = 2998

拼多多也不带怎么玩的啊。。。

这就造成了广告主账户里面没钱了,但是广告依然给他投放了出来。因为广告系统用户缓存余额远大于账户系统的余额,当缓存余额小于0时会触发一个广告下架的操作,这样就一直得不到触发,并且由于账户没钱了,广告系统一直收到扣款失败的消息,疯狂继续补余额。。。


三、修复措施

1、精度处理:联系账户系统的同学,将消息里面增加一个精度scale字段,如scale = 3,对应将amout / 1000

2、对扣款失败消息为账户余额不足一类的消息,不做补回余额操作

  然后发现代码有个这样的注释,那我就好人做到底了,顺带做了

  //伪代码

Long setnx = redis.setnx(业务Key+唯一消息id,"1");
redis.expire(业务Key+唯一消息id,x);
if(setnx == 0) return;

你可能感兴趣的:(总结错误篇,bug)