死循环:扣不到的广告余额,记一个生产问题
前言
广告收入在各大互联网公司的营收中占据重要甚至主导地位:
- 字节跳动2020年广告收入1831亿元,占2020年实际收入的77%;
- 百度依靠搜索承接了大部分的网络营销业务,广告营销收入占比一度达到其总营收的90%;
- 谷歌(Alphabet) 广告收入占总营收的约80%;
- Facebook 广告收入占总营收的约98%;
- 腾讯 广告收入占总营收的约20%;
- 阿里巴巴 广告收入占总营收的约60%;
- .....
尽管各大互联网公司的具体广告平台和投放方式可能有所不同,但广告投递流程大致相似,一般包括注册登录、创建广告账户、设置支付方式、创建广告计划、设计广告创意、定义受众定向、设置出价策略、提交广告审核、广告投放、数据分析与优化等步骤。
点击查看步骤说明
-
注册并登录广告平台:广告投递者需要在相应的广告平台上注册并登录,如谷歌Ads、Facebook Ads Manager、腾讯广告、阿里妈妈、京东广告等。
-
创建广告账户:广告投递者需要创建一个广告账户,填写相关信息,如公司名称、联系方式、地址、行业等。
-
设置支付方式:广告投递者需要为广告账户设置支付方式,如信用卡、支付宝、微信支付等。部分平台可能要求预先充值一定金额作为预算。
-
创建广告计划:广告投递者需要创建一个广告计划,设置广告目标(如品牌推广、网站流量、应用下载等)、预算、投放时间等。
-
设计广告创意:广告投递者需要设计广告创意,包括选择广告格式(如图片、视频、轮播图等)、编写广告文案、添加呼叫操作按钮等。
-
定义受众定向:广告投递者需要根据目标客户群体设置受众定向,如地域、年龄、性别、兴趣、行为等。
-
设置出价策略:广告投递者需要为广告设置出价策略,如CPC(每次点击成本)、CPM(每千次展示成本)、CPA(每次行动成本)等。
-
提交广告审核:完成广告设置后,广告投递者需要提交广告创意进行审核。广告平台会根据其广告政策对广告进行审核,确保广告内容合规。
-
广告投放:广告审核通过后,广告将按照投递者设置的计划、受众定向、出价策略等进行投放。广告投递者可以在广告平台上实时查看广告投放效果。
-
数据分析与优化:广告投递者需要定期分析广告数据,如曝光量、点击量、转化率等,根据分析结果对广告计划、创意、定向等进行优化,提高广告效果。
问题现象
月初对账,部分客户账单异常,扣费额超出余额,超限投递了广告。
背景:广告扣费流程
假设您是一位广告投递者,在某平台投放广告后,服务商的扣费流程一般可以简化为如下:
为了让客户有更好的体验,一般最后只要账户还有余额,就进行一次抵扣,直到账户的余额扣完,让利给客户。所以上面标红的部分变成了:
实际流程
因为每次曝光的费用都是在广告投递的时候配置好的,所以扣费时的 payamt
支付金额是从配置中获取。这个时候如果想要将余额抵扣完,一般需要进行两次抵扣,第二次抵扣的金额依赖于第一次抵扣时候抵扣接口返回的账户余额,然后使用剩下的金额金额抵扣(标黄部分)。
问题原因
直接原因
在某些场景下,客户数据托管系统余额不足时没有返回剩余金额,上游系统直接使用了余额转int
的函数,将余额信息初始化成了 0,导致二次抵扣的系统认为客户已经没有余额,所以没有进行二次抵扣。但是客户数据查询接口能正常查到账户余额,所以广告又一直在曝光。
根因
- 某个中间系统年前进行了重构,代码有 bug(将获取不到的余额信息初始化成了 0),导致在用户信用额度未使用的情况下,抵扣接口返回了剩余金额 0 的信息
- 测试同学场景考虑不充分,仅仅考虑了一种余额不足的场景,没有考虑其他余额不足场景
余额不足场景验证场景较为单一(初始化余额,支付大金额),测试同学验证的场景,刚好命中代码特殊逻辑分支,返回了余额。
出现上面的现象之后,内部进行了排查,定位流程非常复杂:
- 系统间调用链路很复杂
- 所有系统都没有业务告警或者系统异常,意味着所有的逻辑都正常处理了,有定位经验的大家应该都知道这样的问题最难定位。
- 执行二次抵扣的系统长时间没有版本导致几乎无人知道这个逻辑
- 那个月发布的版本很多,无法确定是什么版本引入的
- ....
那么有没有什么手段能提前发现这些问题呢?
重构版本常见验证方法
并行测试
并行测试 :在重构前后的系统上同时运行相同的测试用例,并对比测试结果。这种方法可以确保在相同条件下对两个系统进行对比,从而发现潜在的问题和差异。
优势
- 可以在相同条件下对两个系统进行对比,提高测试的准确性。
- 可以快速发现潜在的问题和差异。
限制
- 需要额外的资源和时间来同时运行和维护两个系统。
- 可能无法完全模拟真实用户的行为和场景。
- 存在自动化用例的改造工作量:
- 需要对全量返回字段进行全量比对改造
- 需要对全量持久化存储的字段进行了全量比对改造
- 少数的不能完全一致的数据,需要逐个确认,或者验证其满足一定规则,不够精确,时间耗费较多
PS:自动化用例在编写之初就一定要设计好,才能在后续方便改造。
现网引流
方法一可以帮助简化对测试结果的验证,但是测试输入还是人工构造,与实际调用可能存在差异 且 不够丰富,漏掉一个场景就有可能放过一个bug。所以直接使用线上的请求测试在辅助验证方面是一个高效的方法。
但是这种测试方法有一定的局限性。简单来说,这种方式适合测试读接口,不太适合或者说是难以测试写接口。
优势
- 请求场景丰富、高效
- 可以快速发现潜在的问题和差异。
限制
- 需要进行请求聚合,不然测试环境无法支撑请求量
- 直接使用线上的存储时,只适合测试读接口,不太适合或者说是难以测试写ni接口
- 测试环境拷贝线上数据时:
- 安全风险
- 流量发生与用户数据拷贝无法同时完成,所以引流主要是验证变化,而不是与现网进行对比
其他验证手段
以下是服务转运维之后,在线上可以做的一些质量保证的方法:
测试方法 | 方法介绍 |
---|---|
A/B测试 | 将用户流量分为两部分,一部分访问现有系统(A),另一部分访问重构后的系统(B)。通过比较两个环境下的用户行为、性能指标和转化率等数据,评估重构前后系统的差异。 |
蓝绿部署 | 在两个不同的环境(蓝环境和绿环境)上部署重构前后的系统。通过将流量切换到不同的环境,可以实时观察和比较两个系统的性能和功能表现。 |
影子部署 | 在重构后的系统上部署一个影子服务,该服务接收与现有系统相同的请求,并在后台运行。通过比较两个系统的响应和性能数据,可以评估重构前后的差异,而不影响用户体验。 |
混沌测试 | 在重构前后的系统上同时引入故障或异常情况,以评估系统在不同环境下的稳定性和容错能力。混沌测试有助于发现潜在的问题,并确保系统在各种故障情况下的处理逻辑保持一致。 |
线上验证的优势和限制
测试方法 | 优势 | 限制 |
---|---|---|
A/B测试 | - 可以直接观察真实用户在两个系统中的行为和反馈。 - 可以实时调整流量分配,根据测试结果优化系统。 |
- 可能需要较长的时间才能获得足够的数据来支持决策。 - 需要确保用户在A/B测试过程中的隐私和数据安全。 |
蓝绿部署 | - 可以实现平滑的系统升级和回滚,降低风险。 - 可以实时观察和比较两个系统的性能和功能表现。 |
- 需要额外的资源和成本来维护两个不同的环境。 - 可能需要复杂的流量切换和监控机制。 |
影子部署 | - 可以在不影响用户体验的情况下评估重构前后的差异。 - 可以实时收集和分析两个系统的响应和性能数据。 |
- 可能需要额外的资源和成本来部署和维护影子服务。 - 由于影子服务在后台运行,可能无法直接观察用户的反馈。 |
混沌测试 | - 可以评估系统在各种故障情况下的稳定性和容错能力。 - 可以发现潜在的问题,提高系统的可靠性。 |
- 可能需要专门的工具和技能来设计和执行混沌测试。 - 混沌测试可能引入不稳定性,需要在安全的环境下进行。 |
在实际应用中选择适合的方法时,需要根据项目需求、资源和风险承受能力等因素进行权衡。
总结
信息在多个系统间传递的时候,很有可能会失真,每一个生产事故的背后,都是宝贵的经验和教训,都是项目成员的血泪史,保持敬畏。
在进行对比测试时,务必确保测试用例完整、测试数据一致,并关注测试过程中的问题和反馈,进而评估重构前后系统的性能、功能和稳定性,以确保处理逻辑的一致性。
同时对比测试也有助于发现潜在的问题,从而提高系统的质量和可靠性,有条件的可以根据实际情况结合使用多种方法,应用到日常版本中去。
合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。