vivo 浏览器福利体系架构演进之路

作者:vivo 互联网服务器团队 - Zhang Xian、Zhang Baolin

vivo 浏览器为应对多场景金币激励需求及旧架构流量、IO等痛点,升级福利中心架构。服务层面拆分流量与业务,打造金币集散中心;数据层面分库分表、拆解大表并优化流水设计;通过仲裁系统和软事务保障数据一致性。改造后,系统可支撑千万级DAU,性能稳定提升,物理存储成本降低,解决了流量与存储压力,成为高可用可复制架构,且将持续迭代保持竞争力。

1分钟看图掌握核心观点👇

一、业务背景

在数字化产品的运营策略中,金币激励体系作为一种行之有效的用户激励手段,正被广泛应用于各类平台,尤其是在内容消费类为主导的资讯,短视频、小说、短剧等赛道的APP中,金币激励能够让用户更好地体验到产品带来的价值和服务。它通过虚拟金币的发放与回收,改变用户行为,提升用户参与度、活跃度和忠诚度,为平台创造价值。

vivo浏览器作为vivo互联网生态中的内容媒体,早在2021年就已经引入金币激励体系,在浏览器小说渠道做产品运营与金币用户培育。在2024年初,由于在内容赛道与非内容赛道(如美团,拼多多等),均已上线金币激励体系。vivo浏览器的产品生态急需升级,经过多方面考量,决定在视频tab场景尝试接入金币激励体系。所以业务需求应运而生,而老旧的架构体系,无法满足vivo浏览器的大规模用户带来的流量冲击,故技术团队开始着手浏览器福利架构的升级工作。

二、技术痛点

早期的架构单纯支撑vivo浏览器小说用户,设计相对原始,宗旨是满足当前业务即可,基本架构图如下:

初期的架构设计比较简单,数据库没有做分库,仅针对用户做hash分表,对金币流水做按月分表,定期创建,定期删除。

初期业务流量较小,基本没什么问题。随着业务的不断发展,金币玩法愈发多样化,这套设计无法满足以下业务场景

  • **任务玩法多:**金币玩法越来越多,定制化逻辑越来越复杂,单服务既要完成任务流转,也要完成金币流转,功能划分不够清晰,代码复杂度增高。

  • **服务压力:**vivo浏览器带来的大规模用户流量,从百万级DAU预计增长至千万级DAU,当前架构无法通过扩容等手段来解决问题。

  • **IO瓶颈:**由于是单库设计,偶尔出现数据库性能问题。

  • **金币泄露:**对账逻辑较为朴素,无严格的数据一致性校验。

  • **安全漏洞:**风控策略存在遗漏,容易成为黑灰产的攻击对象。

鉴于以上问题,技术团队开始着手对现有架构做改造和升级,以支撑日渐增长的业务诉求。

三、架构升级

针对以上痛点,结合当前业务需求和未来的业务发展动向,我们架构设计需要考虑支持几点:

  • **支持多形态任务玩法:**通过细化服务功能,抽象任务状态机流转模型,快速支持各种形态的激励任务。

  • **支撑大流量:**结合浏览器流量特点,设计出一套满足高并发高性能的服务群架构。

  • **IO无压力:**通过集成分布式数据库,缓解大流量带来的数据库压力。

  • **数据安全:**需要满足金币数据的高精度准确性,确保用户资产安全。

  • **风控严格:**通过完善的风控机制,精准定位黑灰产,降低业务运营成本。

此外,新架构设计还考虑到以下两点:

  1. 支持业务动态扩展:

    架构清晰简单,每一个服务中的模块分工明确,低耦合,方便水平扩展,支持业务快速迭代。

  2. 低成本可复制

    注重底层数据逻辑的可重用性,为以后多套代币业务提供服务模版,提高开发效率,降低时间和人力成本。

综上,我们需要打造一整套完整的福利中心架构体系,围绕金币激励解决直接关联的问题,以及相关衍生的问题。

我们的目标是围绕用户时长增长和商业化变现能力提升,打造出一整套由配置管理,任务流转,金币集散,安全风控和基础能力组合而成的福利中心能力矩阵,缔造一个支持多场景增强的可复制架构。

四、改造方案

针对当前问题,结合物理资源的限制,技术团队从以下几个方面着手,对系统进行改造升级。整体架构设计图如下:

4.1 服务层面

4.1.1 流量隔离

按照流量入口,拆分服务,将浏览器小说业务,浏览器信息流业务,浏览器通用业务,拆分开。域名统一,通过path定向分发到各自服务。

服务拆分

根据同一代币同一系统原则,拆分浏览器金币业务和趣阅金币业务。二者独立迭代,独立发展,风控策略独立,仲裁系统按照业务维度区分数据,但能力公用。两套服务群功能可借鉴,服务可复制。

4.1.2 金币互通

收口金币管理相关功能,打造全新的金币集散中心,管理各渠道的金币增减行为。金币互通模块的基本功能架构拆解如下:

4.2 数据层面

针对原有单库的性能瓶颈,对数据库进行如下改造:

4.2.1 分库分表

分库按照用户维度一次hash,分表按照用户维度进行二次hash。根据浏览器全网用户存量,分为N个库,每个库M张用户表。

4.2.2 大表拆解

拆分原有的用户大表,将订阅,抽奖等信息独立建表,用户表只存放最关键的金币总额信息。订阅,抽奖等表项,只为push等业务运营场景使用,极大降低因全表扫描导致的数据库性能瓶颈。

4.2.3 结余设计

重新设计金币流水信息表,增加用户金币月余表项,改造金币消费扣减的逻辑,避免因为扣减导致的一次查询多张表项,提升性能。

在原有系统中,金币流水记录表设计中,是按月分表,表项里面有两个重要信息,一个是当前流水金币净得数量,另一个是当前流水金币剩余数量。金币扣减时,需要循环遍历用户的每一条金币流水记录,逐一扣减,同时需要记录每一个用户扣减到哪一条流水记录。对于中低活用户,一次扣减可能需要遍历查询12张金币流水表,逐一扣减。如下图所示:

用户1扣减时,按照时间由远及近,逐一扣减每一条流水记录,若当月表不够扣减总额,则继续找下一张表即系重复此操作。因此,在极端情况下,性能较差。平均情况下,由于每次的操作记录数量不可控,所以性能波动较大,接口RT不可控。

鉴于此问题,新系统对金币流水表按照用户分表,同时根据业务需求,金币流水只存储最近N个月的流水明细,方便用户查看明细。超过N个月之前的流水自动归档到月余表中,删除N个月之前的金币流水。并且完整流水记录按月离线备份到hive中。归档公式如下:

每次用户扣减金币时候,只需要将月余信息拿出来,由远及近直接扣减即可,单表一次性操作,性能得到了极大提升,同时不会因为低活用户而遍历多张表,所以性能非常稳定。另外,这样极大地压缩了数据库存储空间。

4.3 数据一致性

4.3.1 仲裁系统

旧的架构没有考虑对金币的数据准确性做强一致性的校验,所以会收到客诉,对口碑造成一定负面影响。

新架构集成了仲裁系统,包含对账,复核,平账,补偿等功能。多种条件会触发用户金币的对账,确保金币数据的一致性,同时配合审计复核,实现精准对账。

对于复核失败的用户,新的架构新增离线数据任务系统,集成即时通知,实时查询历史数据等功能,方便运营和开发人员及时处理,降低FAQ频次,提升口碑。

4.3.2 软事务

福利中心金币领取、提现、权益兑换部分场景涉及到跨服务调用的情况。由此带来分布式事务数据一致性的问题,我们采用了软事务来处理这些一致性问题。

金币增减通过单库事务实现,跨系统或者跨库由轻事务负责,用来减少编码难度,避免TCC的侵入。

金币领取场景,使用订单id对每笔金币领取进行绑定,以便追踪金币领取状态。接口网络异常时快速通过订单id确认订单状态,记录未成功的订单,进行离线补偿。以确保金币领取最终一致性。

4.3.4 小结

经过以上几方面的改造和升级,我们将一个以金币驱动单场景朴素逻辑结构,改造升级成为一个场景增强型的高可用可复制架构,以支撑业务的发展需求。

五、结束语

vivo浏览器福利中心,结合业务需求,针对原有架构痛点进行改造和升级,成功解决了原有系统的流量压力和存储压力,月余设计巧妙地结合业务,极致压缩了物理存储成本的同时,改进了金币扣减逻辑,使性能得到稳定提升,成为支持千万级DAU无风险运行的一套服务群。架构升级过程中,还有许多细节点,由于篇幅限制,不再一一赘述。

架构升级不是终点,而是新征程的起点。我们在业务不断迭代的过程中,一直在不断尝试使用新思路,持续打磨架构,让其在动态变化中保持行业领先的竞争力。

相关推荐
千寻girling43 分钟前
主管:”人家 Node 框架都用 Nest.js 了 , 你怎么还在用 Express ?“
前端·后端·面试
南极企鹅1 小时前
springBoot项目有几个端口
java·spring boot·后端
Luke君607971 小时前
Spring Flux方法总结
后端
define95271 小时前
高版本 MySQL 驱动的 DNS 陷阱
后端
忧郁的Mr.Li1 小时前
SpringBoot中实现多数据源配置
java·spring boot·后端
暮色妖娆丶2 小时前
SpringBoot 启动流程源码分析 ~ 它其实不复杂
spring boot·后端·spring
Coder_Boy_2 小时前
Deeplearning4j+ Spring Boot 电商用户复购预测案例中相关概念
java·人工智能·spring boot·后端·spring
Java后端的Ai之路2 小时前
【Spring全家桶】-一文弄懂Spring Cloud Gateway
java·后端·spring cloud·gateway
野犬寒鸦3 小时前
从零起步学习并发编程 || 第七章:ThreadLocal深层解析及常见问题解决方案
java·服务器·开发语言·jvm·后端·学习
Honmaple3 小时前
OpenClaw 实战经验总结
后端