百度 App Feed 流业务架构变迁思考和升级实践

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. 百度 App Feed 流业务架构 变迁思考和升级实践 李哲浩 Baidu Feed Android Architect
2.
3. • 过去的架构漫步 • 大环境的冲击 • 采用的架构思想和原则 • 若干场景的架构示例 • 架构维护控制
4. 从仓促开始 频道A 展现层V 频道B 展现层V” Android 三方库 控制层C 业务逻辑层M 网络 日志 框架 Android RN 三方库 控制层C” 基础设施 DB 频道C 业务逻辑层M” 基础设施 DB” 网络 日志 框架 整体组件化 频道D Feed业务组件 Feed SDK Hybrid Copy 用例不多,不够重视 迭代不多,不够复杂 团队视野受限,经验不足 重构就是物理搬移、单例满天飞 征战状态,时间紧 工程化平台不够完善 核心业务深入迭代,产品需求不断叠加 还没做好,别人就要用 遗留代码基大, 架构老旧不敢改 模型复杂,系统僵化、脆弱、晦涩
5. • 过去的架构漫步 • 大环境的冲击 • 采用的架构思想和原则 • 若干场景的架构示例 • 架构维护控制
6. 行业众软件架构模式 MVC MVP PAC (HMVC) MVVM MVI model-view-controller model-view-presenter presentation–abstraction–contro l model-view-viewmodel model-view-intent ECB ECS OBR MOA SOA DCI data-context-interaction CQRS entity-control-boundary entity-component-system object-request-broker message-oriented-arch service-oriented-arch Command-Query Responsibility Segregation Hexagonal Onion DDD Clean Redux Flux N-tier Event-driven Plugin-based Component-based Microservices Reactive Systems VIPER VueX MobX Database-centric Micro-frontends Middleware-based
7. 公司平台和环境 Easybox 工程构建 Scheme 协议路由 NPS 插件化 Talos Hybrid Pyramid IoC/服务 组件化 动态化 webview 增强 Crius BdBus OEM mapping 容器化 事件总线 技术中台 RN 中台化 跨端 小程序 数据中台 业务中台 客户端重点技术方向 商业 产品线 内容分发 Feed 搜索 研发 测试 基础技术平台 内容消费 多团队 研发多、测试少 Flutter KMM Jetpack Compose 内容生产 全民小视频 好看视频 百度App 百度贴吧 百家号 音啵 Flow 新流 小度 音磁 看多多 柠檬爱美 百度云 招财猫 慧拍 西番 秒懂 游所为 有驾 多产品线输出 (快速孵化、动态裁剪)
8. • 过去的架构漫步 • 大环境的冲击 • 采用的架构思想和原则 • 若干场景的架构示例 • 架构维护控制
9. 架构影响因素 环境 行业特征 开发方式 业务 价值 组织结构 干系人构成 功能 服务 流程 商业模式 团队成熟度 高 保持满意 关键参与 最小投入 保持知会 权力级别 技术约束 低 低 ROI 数据 利益级别 高
10. 投入成本比 需求 发布 名义粗估 6天 排期 5天(倒排) 开发 4天 测试 1天 发版上线 Bugfix 1.5天 预计加班 1天 含上版本 bugfix 1 天 借调 人力 0.5天 需求 发布 正在开发 下一个需 求 实际粗估 4.5天 研发效率的提升收益如何度量? • 这个需求需要记录几天?6 vs 5 vs(4 – 1)+ (1 + 0.5)x 30% + 1.5 • 我们敏捷迭代平台记录了什么?名义粗估、排期 • 假设架构重构需要1个人1个Q投入,名义粗估不会提升,还投资吗? 重塑度量积累数据 • 假设实际效率有平台度量,确有5到3人天的提升,重构需要投入1年, 若环境变化中断,导致架构四不像,怎么办? 架构重构是否有足够power 需求 回顾 研发质量的提升收益如何度量? 架构升级 架构复辟 脆弱和遗漏带来的bug减少 复用带来的bug减少 真实复用 copy复用 中间件变多带来认知复杂度 并行开发冲突 抽象带来的性能劣化 巨型类加载的性能劣化
11. 团队成熟度 黑箱复用 白箱复用 基本需求/初始代码 扩展需求/继承 新需求/要求复用 原型阶段 重构/分解 通用化 扩展阶段 • • • 争取业务, 野蛮增长, 重复轮子 表现打分 ● 宁可花时间研究fresco,不愿花时间研究打磨现有的项目“复杂”组件; ● 宁可花时间研究花哨的外家功夫,不愿花时间打磨自己的基本内功; ● 不是自己写的代码基本不改,完全无视带来的重复,架构设计的背离; ● 没有制定设计规范,或者存在多套设计规范,互相无法说服,没有顶层架构设计; ● 对单测、代码评审等保障体系建设有抵触,认为给自己带来无意义的麻烦; ● 能copy工作就行,对新技术、团队指标、任何宣贯都漠不关心 ● 团队成员互相不愿意沟通协调解决协作、边界处理等问题 ● 擅长 0-1 Copy,对1-n没有自己的想法,处处依赖上面的指定 框架化 标准化 萎缩阶段 巩固阶段 • • 争抢标准,争抢输出 你造汽车,我造航母 • ROI至上,强调先验 俄罗斯方块类比 重视地基 重视拼接正确性 有code review比没有code review强, 没有code review比有code review强, 同样适用于测试,即没有勇气,只想遵循规则而不是坚持原则
12. 业务复杂度 • 做一个转换器插件,将RGBA的颜色数组转化成YV12格式的颜色数组 技术复杂度可以很高,业务复杂度低 • 做一个简易弹窗提醒(弹窗无要求),有上百种情况,不同情况组合(协同、互斥、相互作用) 下,弹窗的文案不同 技术复杂度低,业务复杂度可能很高(熵很高) • 文件写入也可能有多种异常情况要处理啊? 文件处理是您的主要业务吗? 难以理解,难以整合,难以预测
13. 团队成熟度和业务复杂度 复杂业务 简单业务 强制或重组 过度设计 领域模型设计 放任 样板间设计 简单设计 自由人 工具人 敏捷人
14. 什么应该是模型 { "is_vip":"1" "data": { … } "pass_through": { … } vipTitleColor="#FF0000" title="<b>" + data.title.substring(0, 1) + "</b>" subtitle=data.title.substring(1) } 展现模型 isVip=true 云控模型 if (isVip) { // 解锁 // 更新ui } 业务模型 id | xxxxxx | { … } } json { "is_vip":"1","data": 存储模型 关注业务模型  模型应该能用于不同角色的交流  模型是业务需求分析的设计表达, 使业务规则显明化  聚焦业务合法性 启动加载8条数据 填满首屏 其他数据延后加载 回填 技术模型
15. KMM的启示 架构层级 是否推荐共享 业务逻辑 是 平台访问 可选,接口化行为(此部分共享),使用平台API 前端交互(输入交互,后端通信) 可选,依赖架构模式 UI展示 否 业务逻辑不依赖基础设施
16. 前端状态管理方案的启示 单向数据流 模型响应式状态化 (而非接口化) 展示层设计    • • • MVI Redux Flux UI被动渲染 UI不能更改状态 UI传递抽象意图 VueX MobX Bloc   一个意图或事件可能多次切换状态 UI只是观察状态变化触发render方法
17. 后端前沿架构的启示 依赖方向 Query 接口 驱动/主适配器 基础设施 被驱动/次适配器 Command Controller Entity actor/UI Moment Interval Presenter Value Object Context Gateways Interactor Entity Control Adapter Data • 框架/基础设施 Entity Converter Port event Adapter 其他上下文 四色原型 DCI Clean • • bridge Adapter Command DDD • • 核心 单测/脚本 • 网络库/Server Methodful Role Boundary • Description Methodless Role • • Remote source Domain Event • • IO Adapter Party Place Thing Use Case Local source Domain Service Aggregate Role 存储/Database Repository 领域层 Application Service IO Port 应用层 特点 ECB/EBI • • 依赖反转,端口适配 里层不依赖外层 不再依赖基础设施 不再嫁给框架 边界清晰 领域模型为核心 业务逻辑不泄露 关注点分离 富血模型 用例整洁 业务维度隔离 易于单测 易于维护
18. 快速开发的思考 Feed的同学 比较深入,难度大 核心业务实现 已具备 外部团队同学来Feed 无法实现快速开发 独立模块 独立扩展 可裁剪 可以实现快速开发 大业务认知 概念统一有助于实现此目标 已具备 新入职同学来Feed 重点扩大 这里的辐射范围 “标准化” “边界清晰” 技术栈 工程能力 工具链 新人必备的能力 目前已必备
19. 组件化 壳工程 业务组件A 业务组件B 接口层 模块 业务组件C 下沉通用部分 共用依赖 基础组件X 基础组件Y 基础组件Z 核心 实现层 模块 扩展 实现层 模块 初步组件化 依赖情况 组件A 接口层 模块 接口层 模块 接口层 模块 实现层 模块 实现层 模块 实现层 模块 组件A 组件B 组件C 接口层提取 接口层 模块 接口层 模块 layout xml 实现层 模块 业务基础 组件 实现层 模块 核心组件 B 实现层 模块 扩展组件B‘ 实现层 模块 组件C 贫血 模型 data 实现层 模块 业务组件 业务组件膨胀情况 物理接口层有助于减少依赖环,随迭代膨胀后,产出一些隐式经验规则: A. 适合核心组件和扩展都在一个团队 B. 适合多团队外部扩展,独立发布、组合使用 C. 历史遗留情况  划分组件类型  减少贫血模型,尽可能接口化  减少布局文件,尽可能code as ui(声明式DSL)
20. 组件化 能力集成方式 业务中台组件 泛化(继承/实现) 基础框架组件 包含(聚合/组合) UI组件 Data组件 业务基础组件 基础技术组件 业务支撑组件 调用(依赖/关联) 线程池库、网络库、 图片库等 业务无关 feed容器等 点赞、关注等 业务组件 通用业务 特定业务 组件能力模型 • • • • • 分离通用和业务,进行业务抽象,分离不变和易变 • • 接口层提取容易程度 账号、打点等 组件分类 • 服务化程度 依赖的服务(下游) 提供的服务(上游) 身份 通信机制 生命周期 概念完整性 关系管理(优先级、互斥、协同、容器父子) 动态性(编译期识别/运行时发现,热更新,异常鲁棒性) 业务相关性
21. 边界问题 Id=x • 原则1:组件独立、互不依赖 列表条目数据json • 原则2:谁的PM提需,胶水、脏活这一方适配开发 首页胶水 tid=1 图文落地页 首页列表页 tid=2 push 内容 搜索落地页 sid=1_1 视频落地页 vid=11 我有一套通用 的当前展示内 容的通知机制 搜索落地页 条目2 来自push 电商 重复逻辑 条目3 Back返回 vid=12 我不想调用你 的方法,你提 前注册我 电商胶水 来源是否 锚点条目 sid=1_2 视频落地页 API层 条目1 点击熊掌按钮返回 来自push 首页 视频的通知格式 Back 返回 图文落地页 来源是否 我有一套通用 的锚点插入机 制 没有时机?那 application里 注册? 不想耦合你的通 知的数据结构信 息 业务 组件 胶水/适配 组件 胶水/适配 组件 业务 组件
22. 多产品线方案选型 矩阵产品+创新孵化产品+不同应用市场渠道 差异部分 组件1 新分支 组件1 组件2 组件3 分支方案:跟随者/独立自主 为什么以分支方案为主 差异部分 组件1 接口化 插件扩展 1 组件2 组件3 插件方案:客户和供应商/开放服务 差异部分 组件1 main  两个团队发版节奏不同,时 间不容易match  构建方案版本管理成本大  两个分支差异有工具可以 merge  整体也能得到足够复用  主线定期以矩阵用例回溯改 进接口 common lite 组件2 组件3 构建方案:共享内核
23. 架构升级假设 业务单元 拆解 功能单元 功能单元 调度/分发 功能单元 调度/分发 服务中心 通信 通信 能力单元 能力单元 能力单元 能力单元 能力单元 能力单元 能力单元 能力单元 能力单元 事务脚本 领域模型 表模块 四色原型 DDD战术充血 响应式状态 插件下发 hybrid RN 梯田式架构  不同的子域根据不同的业务复杂度和质量约束, 采用不同的编程范式,建模方式,方法论, 开发构建部署形式 概念完整度、业务模型边界清晰度、 测试覆盖度、团队成熟度、单元细颗粒度 是架构可以自然升级的保障 升级 业务用户量上涨 单测  调度/分发 事件中心 升级 单测 不单测 交互定制 易维护性 快速开发 NA 业务变复杂 领域模型 MVC MVP Compose 能力单元由于粒度细,可以边重构,边进行产品需求开发,重构周期短,有单测验证保障 VS 标准化架构模型:大炮打蚊子,但认知迁移负担小
24. 迁移和升级准备 简单列表 简单列表 简单列表 业务自增逻辑层 弥补三级列表中台能力不足 复杂列表 三级列表中台组件 带通用业务策略的列表 可刷新的通用列表 • 最小级 • 通用业务级 • 饱满业务级 基础列表 架构现状    架构割裂,四不像,维护成本高 复杂列表业务痕迹严重,难复用,中台难落地 三级列表中台能力薄弱,其上业务重复造轮严重 提前做培训 升级问题    权力变更、无法持续投资 设计之初未分析好重点对象,另起灶炉、天马行空 没有做好培训引导、推广 不接受四不像,重塑?
25. • 过去的架构漫步 • 大环境的冲击 • 采用的架构思想和原则 • 若干场景的架构示例 • 架构维护控制
26. 定义结构和语义 组件 Processor 业务逻辑组件 连接件 Page UI抽象组件管理者 消息 Action 连接核心业务逻辑和 基础设施、父容器、异构容器 约束 (部分摘录) Ability Extension 基础设施抽象组件(UI) Process Context 业务逻辑组件管理者 生命周期管理者 服务发现者 事件派发者 业务扩展组件 Plugin Assistant 可动态下发的 一类业务扩展 集合 对外服务接口 Extension Point 连接核心业务逻辑和 扩展业务逻辑 • Processor中仅能接受以Ability身份封装的基础设施的交互,不能出现具体的视图类、数据存储类等 • Processor间不能互相直接交互,可以以Assistant的身份交互,或者基于Action消息交互(适合单向单工) • Ability是基础设施的被动封装,谦卑对象, Ability间的交互只能发生在Page、Repository、 DataSource、UnitOfWork等连接件中 • Processor、Ability都可以进行复合使用,但ID标识符应虚拟,并设置为可查找内部组件 • Processor是基于“主营”业务设置的,通用时机应设计Action消息,非通用时机需要设计为Extension Point,供外部注入Extension, 禁止非“主营”特定业务以分支(if-else)的方式污染Processor • 各种组件应附着在对应生命周期容器的Process Context里,禁止自建不必要的ID标识符Map、单例等分散的全局引用
27. 事件-组件-系统 Action Action Processor UI 回调1 … 回调N UI 业务a 业务b 业务a Action1 Processor b … Processor a Processor Processor Event ActionN 事件 转换 器 Action Action Processor Processor c Action 业务c Processor Processor Action Event Sourcing Redux动机/收益 CQRS 单向数据流,预测性好 UI只基于状态更新,Data驱动UI 无缝衔接类React思想组件 全局app级state树实现内存数据库 单一数据源置信 State不可修改,无副作用 从测UI变成测状态,易于单测 树状reducer集实现模块化 纯函数,增强组合能力
28. 上下文框架 getProcessContext()#query(AssistantA.class) Create View ID 外部组件事件 提供的Assistant服务 Touch 依赖的Assistant服务 Extension Point 1 Extension Point 2 Extension Point N load Extension Manager Assistant Manager 服务注册和发现 Dependency Manager Process Context Processor Scroll ID规则管理和组件查找 Processor Container Extension N Assistant N 页面状态 监控 刷新 数据同步 模板 网络状态 运营 … 映射Action的ID 派发Action流 查找能处理的Processor集 提取组件对外接口 回调组件注册观察者 按依赖拓扑排序 业务维度划分的Processor集 Ability N 编排引擎 Page Repository 框架提供的Process Context能力 Action Dispatcher State Map parent 自定义的Process Context属性 Process Context Plugin/Bundle 三方框架回调
29. 复杂业务-DDD战术设计 模型 Message 1 Params 3 1 1 Params 2 1 3 7 4 5 6 1 0 8 9 1 2 1 4 1 6 1 5 最终显示 ① 读取缓存数据 一次feed流 数据源 还原历史 ② 请求网络数据(下拉) ③ 请求网络数据(上滑) ④ 解析数据 去重 ⑤ 装配数据 ⑥ 执行云控策略 Action ⑦ 置顶数据去重 Command 重复上滑 冲突 ⑧ 普通数据去重 ⑨ 清理过期数据 刷新时间 间隔 频道信息 一次feed流 刷新协调 DomainEvent 基础设施层 Infrastructure Layer ⑩ 处理黑名单数据 ⑪ 加载更多历史数据 ⑫ 缓存数据 ⑬ 回填数据 ⑭ 插入数据到列表头部 ⑮ 插入数据到列表尾部 ⑯ 通知列表刷新
30. 展示层设计 无视图控制图层 播放器组件 视频播放区 手势图层 消息 中心 loading/fail/empty状态图层 WebView组 件 运营槽位 作者信息槽位 RN组件 运营视图图层 控制UI图层 列表组件 推荐区 点赞组件 操作 槽位 背景图层 评论组件 评论区 页面图层化 页面槽位分区化 关注组件 收藏组件
31. 展示层设计 Page 业务组装工厂层 推荐 Factory 心潮 Factory 热榜 Factory … Factory Layout Ability 页面实现层 能力实现层 ListView Page JetpackCompose Page Update RecyclerView实现 Update Compose实现 Navigate实现 Refresh实现 … Page RecyclerView Page 列表 图层 items 页面接口层 能力接口层 other abilities 能力可注册 能力可查找 能力可发现 能力可替换 Adapter Ability Footer Ability 可点击Footer实现 Popup实现 加载型Footer实现 … 实现 Empty View Ability Refresh Ability item UI Page 槽位分区 items Page items other items Page data Update Ability Popup Ability Navigate Ability 页面能力接口化 … Ability Data processors 适配融合(父子)
32. • 过去的架构漫步 • 大环境的冲击 • 采用的架构思想和原则 • 若干场景的架构示例 • 架构维护控制
33. 架构评价和特征度量 演进式架构是支持跨多个维度进行引导性增量变更的架构,而架构的适应度函数为这些架 构特征提供了客观的完整性评估 --《演进式架构》 ATAM/SAAM GSM-QUANTS 稳定性/抽象性度量 McCabe圈复杂度 认知复杂度 霍尔斯特德复杂度 DSQI MOOD
34. 架构能力评估模型 团队成员 • 是否有经验丰富的架构师 • 成员多大程度有一致的目标和价值观 开发过程 • 过程是否已定义、或已量化管理 • 有无采用敏捷开发模型、快速开发模型或有效的项目管理 • 成员中有大中型重构设计经验的比例 组件、工具、平台 • 是否有组件库并有足够的组件、以及检索能力 • DevOps平台能够多大程度智能阻止不规范 成本 • 是否建立了有效的效率、质量、需求满足度、业务收益等的度量机制 • 架构防劣化可持续性、决策可逆性这些的难度 • 自动化工具占全开发工作的占比 决策 • 常规问题决策是否有路径规范可循 • 决策者是否有足够的权力和责任,不受干扰 • 决策的质量和效用能否量化、有无反馈考核机制 规范制度、最佳实践 • 规范、最佳实践的数量和质量 • 规范、最佳实践的普及、奖惩、遵守情况
35. 劣化度量监控 • Emacs编辑器可以煮咖啡? 理念:离开发者手边越近的东西就越有价值。不离开IDE就能提供帮助的优于离开IDE • 单例的最好写法是静态内部类方式还是契约规范? 理念:钩子(或切面、插桩)铺开的越多,越规范,就越可控,统计价值越大,架构决策越有效,也越能够自动化。
36. 度量-IDE插件
37. 度量-平台建设 管理平台 考试平台 规范文档平台 组件质量度量平台 DevOps
38. 架构过程回顾 • 架构需求分析 • 质量属性甄别 • 架构风格选型和改造设计 • 架构评审 • 架构准备、架构实现和组件库建设 • 架构维护和监控平台建设 并行开发、快速启动业务和支援、业务动态下发、尽可能免测、减少质量问题 可维护性、可复用性、可扩展性、可测试性 梯田方式,以低迁移成本改造为Redux + Hexagonal + DDD等 简易ATAM(架构权衡分析方法) 架构能力评估、培训、迭代速率度量、权力和完整性、标签建设 6+适应度函数、IDE和DevOps并重、测试体系和个人贡献挂钩
39. 架构升级实践收益 测试体系保障 开发效率 所有NA频道相关业务已全面迁移复用 核心业务单测覆盖率从0变成60%+; 可归因的效率提升10-20%; 接入架构组件来快速孵化相关业务, 自动化白盒测试覆盖了刷新主要场景 主要来自免测、非单点开发者 并行开发、动态裁剪 决策和设计自由度 平台和能力提升 业务模型边界清晰,依赖关系整 洁,扩展性好,标准化程度高 业务维度隔离,各业务可以更好的根据 自己的特点进行维护和质量权衡点决策 基础配套设施更全更智能, 输出复用收益 聚焦、认知成本降低 架构升级经验和框架沉淀, 团队sense提高、工作强度降低
40.
41.
42.
43.

Home - Wiki
Copyright © 2011-2024 iteam. Current version is 2.139.0. UTC+08:00, 2024-12-23 19:08
浙ICP备14020137号-1 $Map of visitor$