通用详情页的打造

背景介绍

图片

大家都知道,详情页承载了站内的核心流量。它的量级到底有多大呢?

我们来看一下,日均播放次数数亿次,这么大的流量,其重要程度可想而知。

在这样一个页面,每一个功能都是大量业务的汇总点。

作为用户核心消费场景,详情页不仅需要承接各种业务的转化,还要负责展示各业务在播放页的功能。

可以说,播放页的代码复杂度属于客户端最高的代码之一,这不仅因为播放页本身的功能复杂,还因为它需要融合大量外部业务功能。

复杂的功能自然会带来较高的代码复杂度,而高代码复杂度往往意味着高代码维护成本。

明确需求

图片

我们来看一下没有做这个项目之前的状态。如图所示,他们分别为三个业务团队各自维护。页面间相互独立。能力无法复用。

图片

通过这个项目,我们要将他们融合成了一个页面。产品的诉求就是将他们融合为一个,来达到多业务形态统一的目标。

图片

但是,这三个详情页并不像产品想象的那么简单。

每个业务都有自己的特殊形态,如大型活动态、主客态、播单态、PUGV/OGV态等一系列业务形态。

每种形态都有自己的特殊逻辑,而且这些业务形态间还可以互相切换。

需求分析

为了更好地达成目标,我们需要进行如下思考:

  • 从业务角度:

要解决多业务形态不统一的问题。例如,产品既想要UGC大型活动的能力,又想要OGV的多视角功能。

但这两个能力在之前分别是两个业务团队各自开发的,无法复用,产品在业务选择上无法兼得。

  • 从效率角度:

要解决迭代方式不统一的问题。例如,进度条体验优化需求,产品在给UGC团队提需求的同时,还要复制一份给OGV团队。

两个业务方的开发和测试都需要进入这个项目,并且双方的开发进度和排期可能不一致。如果产品强烈要求同一版本上线,还需要协调各方资源。

  • 从质量角度:

要解决如何保障稳定性的问题。例如,多团队协作,之前都是组内同事协作开发,现在融入了两个新的业务团队,我们该如何保障稳定性。

  • 从团队角度:

要解决如何让新人快速上手的问题。正常情况下,新人想要进入开发必须对这个系统足够了解后才行。

更何况现在变成了三个业务融合的页面。有没有一种手段,让新人无需关心复杂的业务形态和业务逻辑,只需要关注自己的需求?

具体方案

针对以上问题,我们可以总结出通用详情页框架必须满足以上三点,分别为:复用性,灵活性,稳定性

图片

接下来我们继续对多业务形态进行分析。

首先我们从横向上进行拆解,通过对比,我们可以发现

多业务形态间其实有很多的相同模块。如互动,弹幕发送框,相关推荐等。

从纵向上进行拆解,我们也可以发现很多相同模块,如弹窗管理器,主题组件,转场组件等。

那么从横向和纵向上我们发现,多种业务形态间其实有很多可以复用的能力。

图片

基于前面的思考,我们设计了一套通用详情页的框架。将其分为三层:

  1. 业务层:将业务模块分为两类,能够在多业务间复用的模块抽象到通用业务,业务独有模块则由各业务自行负责。

  2. 组件层:抽象出各种通用组件,业务方可自由选取和组装。

  3. 框架层:抽象生命周期管理、数据管理等核心逻辑,以此来保证整个详情页的稳定性。

这样我们就初步解决了复用性的问题,但是随之而来的就是灵活性问题。

图片

我们以实际场景为例,相关推荐模块在课堂态不展示,但是在ugc和ogv下需要展示,另外他的点击事件在ugc和ogv下还会出现差异。

同时相关推荐模块还强依赖简介模块。因为简介模块也是一个通用组件,业务方可以自由替换。

如果哪天业务方替换了了简介模块,那相关推荐模块将无法正常运行。

从相关推荐这个例子我们可以得出如果想让业务模块复用,必须满足两个条件。

  1. 支持业务异化,即允许业务能插入自定义逻辑,否则现在抽象的通用模块在迭代的过程一定会变成非通用,或者里面掺杂各种if else逻辑来支持异化。

  2. 必须保证模块间相互独立,因为所有业务逻辑在此框架下都变成了模块,模块是可以由业务方自由选择的。

图片

引入依赖注入

因此,我们需要在流程和模块中加入依赖注入的能力,用于业务方实现差异化逻辑。

业务方可自行插入自己的业务逻辑,并选择或替换业务模块。来解决模块间的耦合。

定义依赖注入容器

public class BlocStore {typealias StoreLock = RecursiveLocktypealias StoreTable = [String: BlocTable]private let lock: StoreLock = StoreLock()private lazy var storeTable: StoreTable = [:]
}extension BlocStore {public func register<Service>(service: Service.Type = Service.self, to: Bloc.Type) {let key = "\(service)"lock.lock()defer { lock.unlock() }serviceTable[key] = to}@discardableResultpublic func optional<Service>(service: Service.Type = Service.self) -> Service? {let key = "\(service)"lock.lock()defer { lock.unlock() }let service = resolve(bloc)return s}
}// Bind and unbind
extension BlocStore {public func bindBloc(bloc: Bloc) {}public func unbindBloc<T: Bloc>(_ blocType: T.Type) {}
}// BlocLifeCycle
extension BlocStore {func onStart(bloc: Bloc?) {bloc?.onStart()}func onPause(bloc: Bloc?) {bloc?.onPause()}func onResume(bloc: Bloc?) {bloc?.onResume()}func onStop(bloc: Bloc?) {bloc?.onStop()}
}

组件注册

// 业务方根据业务逻辑可以注入不同的实现
register(service: XXXProtocol.self, to: ABloc.self) // A业务形态
register(service: XXXProtocol.self, to: BBloc.self) // B业务形态

组件解析

let s: XXXProtocol = store.optional()

引入scope

scope分为页面级和业务级两种scope:

class VDScope {public static let core = "store.core.scope"public static let biz = "store.biz.scope"
}

定义 Scope 管理来管理模块的生命周期:

  • Page scope的生命周期与页面保持一致,Biz scope与业务形态的生命周期保持一致。

  • 即在页面形态发生变化时,框架层会自动将bizscope下的所有模块进行销毁。

public class BlocStore {typealias ScopeTable = [String: String]...func bizTypeDidChanged() {// 销毁上一个bizscope下所有模块xxxx// 初始化新bizscope下模块xxx}
}

这样,新人进入开发时无需关注当前业务形态或业务形态切换的问题,达到快速上手的目的。

如何保障吞吐速度和质量稳定?

在开发资源和测试资源不变的情况下,业务范围扩大了,我们该如何保障吞吐速度和质量的稳定呢?

图片

我们可以将策略分为三个阶段:

1.开发阶段:

对于核心流程添加全链路日志,如果发现不符合预期的数据则直接抛出异常。

同时进行技术埋点上报。如果是对于核心流程的修改,强制添加AB降级方案。

2.测试阶段:

有些bug非常隐蔽,在用户体验上可能没有任何差异,但内部流程或数据可能已经发生异常。

对于类似问题,测试根本无法发现。导致此类问题流入线上的风险。我们可以通过添加监控和告警,让我们及时发现问题。

3.灰度/线上阶段:

我们可以通过添加监控和告警,让我们及时发现问题。

具体实施方案:

首先,我们对通用详情页里核心流程添加了全链路日志,并为日志服务添加了两项额外能力:

如果发现日志类型为Error,内部自动触发DEBUG弹窗提醒,并上报技术埋点,达到对线上稳定性的监控。

图片

同时,搭建离在线数据报表和异常告警,进一步保障稳定性。

至此,搭建了通用详情页从发现问题到定向拉取再到快速定位的闭环。

-End-

作者丨凉茶

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/45646.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Web开发手礼】探索Web开发的魅力(三)-html基础标签(3)

上述主要是对html标签的介绍和一些基本练习可以当作日常笔记收藏一下&#xff01;&#xff01;&#xff01; 目录 前言 html基础标签 前言 上述主要是对html标签的介绍和一些基本练习可以当作日常笔记收藏一下&#xff01;&#xff01;&#xff01; 提示&#xff1a;以下是本…

PostgreSQL 怎样处理数据仓库中维度表和事实表的关联性能?

文章目录 PostgreSQL 中维度表和事实表关联性能的处理 PostgreSQL 中维度表和事实表关联性能的处理 在数据仓库的领域中&#xff0c;PostgreSQL 作为一款强大的关系型数据库管理系统&#xff0c;对于处理维度表和事实表的关联性能是一个关键的问题。维度表和事实表的关联是数据…

【手写数据库内核组件】0301 动态内存池,频繁malloc/free让系统不堪重负,动态内存池让应用自由使用动态内存

动态内存管理 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 文章目录 动态内存管…

RSA算法详解:万字文章详解RSA的加密与解密

本文目录 文章前言一、RSA的诞生1、加密算法的前世今生① 《六韬龙韬》中的阴符与阴书② 古罗马&#xff1a;凯撒密码③ 斯巴达&#xff1a;塞塔式密码&#xff08;Scytale&#xff09; 2、对称加密的脆弱性3、非对称加密算法的出现 二、RSA中的数学概念与定理1、质数理论2、关…

使用Qt和mitmproxy开发一个抓取网页短视频的万能工具

目录 实现原理 mitmproxy介绍 功能简介 安装 脚本示例 如何使用 解释 注意事项 QT工具实现 其他资源 实现原理 使用WebView组件造一工具,工具可输入网页地址并显示网页内容及播放视频。把工具的代理设置指向mitmproxy的端口服务。配合使用mitmproxy的MITM技术,监…

7.8~7.10练习

目录 1.扑克牌游戏 2.链表基本功能的实现&#xff08;单项链表&#xff09; 3.移除链表元素力扣 4.反转链表力扣 5.链表的中间结点 5.返回倒数第k个节点​编辑 6.合并两个有序链表 7.链表基本功能的实现&#xff08;双向链表&#xff09; 8.链表分割 1.扑克牌游戏 public…

LightRAG:高效构建和优化大型语言模型应用的 PyTorch 框架

一、前言 随着大语言模型 (LLM) 的蓬勃发展&#xff0c;检索增强生成 (RAG) 技术作为一种将 LLM 与外部知识库结合的有效途径&#xff0c;受到了越来越多的关注。 然而&#xff0c;构建 LLM 应用的真正挑战在于开发者需要根据具体需求进行高度定制化&#xff0c;而现有的 RAG …

Vscode ssh远程连接Linux服务器登录时密码password无法输入

问题 最近在用Vscode远程连接Linux服务器时&#xff0c;在终端提示输入密码password的时候用键盘输入没有反应。 以为是键盘坏了&#xff0c;然后尝试复制粘贴没有用。 后来找到了原因以及解决方法&#xff0c;感谢原帖作者&#xff08;原贴链接粘在下面&#xff09; 原因 …

flutter 列表下拉框加搜索

1.使用控件搜索加下拉框dropdown_search: ^0.4.9和获取中文拼音lpinyin: ^1.1.1 2.加入中文查询和首字查询 在当中找到相应的packages&#xff0c;再在SelectDialog.dart当中加入引入拼音搜索 import package:lpinyin/lpinyin.dart; 更改匹配方法manageItemsByFilter使其可…

有必要把共享服务器升级到VPS吗?

根据自己的需求来选择是否升级&#xff0c;虚拟专用服务器 (VPS) 是一种托管解决方案&#xff0c;它以低得多的成本提供专用服务器的大部分功能。使用 VPS&#xff0c;您的虚拟服务器将与在其上运行的其他虚拟服务器共享硬件服务器的资源。但是&#xff0c;与传统的共享托管&am…

Oracle数据库加密与安全

Wallet简介&#xff1a; Oracle Wallet(即内部加密技术TDE( Transparent DataEncryption&#xff09; TDE是 Oracle10gR2中推出的一个新功能,使用时要保证Oracle版本是在10gR2或者以上 Wallet配置&#xff1a; 1.创建一个新目录&#xff0c;并指定为Wallet目录 /home/oracle…

Python爬虫技术从去哪儿网获取旅游数据,对攻略进行可视化分析,提供全面的旅游攻略和个性化的出行建议

背景 随着信息技术的快速发展和互联网的普及&#xff0c;旅游行业也迎来了数字化和智能化的变革。去哪儿网作为中国领先的在线旅游平台之一&#xff0c;提供了丰富的旅游产品和服务&#xff0c;涵盖了机票、酒店、旅游度假等各个方面。用户通过去哪儿网可以方便地查询、预订和…

STM32HAL库+ESP8266+cJSON+微信小程序_连接华为云物联网平台

STM32HAL库ESP8266cJSON微信小程序_连接华为云物联网平台 实验使用资源&#xff1a;正点原子F407 USART1&#xff1a;PA9P、A10&#xff08;串口打印调试&#xff09; USART3&#xff1a;PB10、PB11&#xff08;WiFi模块&#xff09; DHT11&#xff1a;PG9&#xff08;采集数据…

阿里云操作系统智能助手OS Copilot的实验测评报告

什么是OS Copilot 在老师的介绍下我了解到了阿里云OS Copilot这个产品&#xff0c;它是阿里云推出的一项基于人工智能技术的操作系统&#xff0c;设计用于阿里云Linux操作系统以及其他可能的云上操作系统环境&#xff0c;为用户提供智能化的系统管理和运维支持。 阿里云提供了…

Python数据分析-Excel和 Text 文件的读写操作

1.Excel和 Text 文件的读写操作 1. Text 文件读写包 import sys print(sys.argv[0]) print(__file__) print(sys.path[0]) qopen(sys.path[0] "\out.txt","w",encodingutf-8) q.write(这个是测试一下) q.close() print(done)open 语句可以打开的创建text…

【吊打面试官系列-ZooKeeper面试题】简述 Zookeeper 文件系统?

大家好&#xff0c;我是锋哥。今天分享关于 【简述 Zookeeper 文件系统?】面试题&#xff0c;希望对大家有帮助&#xff1b; 简述 Zookeeper 文件系统? Zookeeper 提供一个多层级的节点命名空间&#xff08;节点称为 znode&#xff09;。与文件系统不同的是&#xff0c;这些节…

白平衡说明

白平衡 相机白平衡的起源原理以及作用起源作用 白平衡的原理白平衡的类型应用说明 工业相机的白平衡效果对比一键白平衡的必要性一键白平衡的实现方式 相机白平衡的起源原理以及作用 起源 白平衡&#xff08;White Balance, WB&#xff09;概念的起源与色温理论密切相关。色温…

【eNSP模拟实验】单臂路由实现VLAN间通信

实验需求 如下图所示&#xff0c;辅导员办公室需要访问处在不同vlan的学生管理服务器的文件&#xff0c;那么如何实现两台终端相互通信呢&#xff1f;我们可以使用单臂路由的方式来实现。 单臂路由&#xff08;router-on-a-stick&#xff09;是指在路由器的一个接口上通过配置…

Spring Boot中@Async注解的使用及原理 + 常见问题及解决方案

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

VMWare 下给Centos扩容

目录 参考文档背景介绍扩容查看当前文件磁盘信息增加一个存储分区创建物理卷把物理卷添加到卷组查看卷组名把物理卷并入卷组 对文件系统进行扩容搞定 参考文档 1、百度经验 2、CSDN 3、掘金 背景介绍 测试环境用VMWare 安装centos7&#xff0c;几年下来磁盘空间不够用了&…