文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

百度十亿级流量的搜索前端,是怎么做架构升级的?

2024-12-03 03:24

关注

 导读:前端发展飞速,从最开始的静态页面到 JavaScript,再从 PC 端到移动端,随着大前端的复杂度不断提升,很多公司开始前后端分离,剥离出前、后端架构设计。那我们来看看,前端架构设计是什么?曾经非常简单的前端架构发展到现在有哪些问题,遇到前端代码体量巨大、跨团队协作效率、代码耦合、技术栈落后等问题又该怎么解决?

Part1一、什么是前端架构?

前端架构这一词,相信很多人的定义都不太一样;按照拆词的解释来看,我理解为“前端”+“架构”。前端是指,Web 端的前台页面,包括网页的内容、样式、脚本等,这三者通常封装在组件中,可能是模板引擎的文件模块,也可能是 MVVM 框架里的组件。“架构”就更好理解了,架构一词来自建筑行业,可以理解是房屋的整体结构、框架。结合前端和架构的概念,“前端架构”可以理解为,Web 页面组件的抽象和组织方式。

又因为各个公司的业务不同,每个公司的前端架构发展都不一样,这里,我会拿百度移动端经典的搜索场景来给大家举例,希望从百度的移动端架构演进过程中,发现一些共性的问题。

Part2二、百度移动端背景及问题

为什么是以百度来举例?是因为百度是国内搜索引擎的领头人,并且,目前一直处于行业领先状态。据 statcounter 前瞻产业研究院在 2019 年中国搜索引擎行中可以知道,百度搜索占全世界搜索引擎市场份额12.3%,居第二位,仅次于谷歌。所以用百度来举例,更具有代表性。言归正传,打开百度 App 你会发现,百度前端直接分为首页和搜索结果页,搜索结果页是搜索的主要入口,每天承载着十亿级流量。

不仅如此,搜索结果页承载着许多产品线的需求和下游模块的运行时,每年内部的研发人员会提供五百多个产品需求,为十几个下游模块提供基础库和运行时。甚至还有后端协同,从图 1 我们可以看出结果页的整体架构。

针对整体的架构设计,有这些问题:

于是,梳理出三个方面的问题:

1. 人员职责不清晰,单个模块同时承担了多个团队的职责

2. 代码耦合严重

3. 技术栈落后

这三个问题最终会影响到研发效率以及产品质量。那么百度又是怎么去具体做的呢?架构优化的目标只有两个,一是满足业务需求,二是技术上能对框架和工具灵活升级(也是为了持续的满足业务需求)。根据“满足业务需求”这一目标,百度内部是制定了三个层面的方向。(如图 2)

Part3三、怎么解决

根据这里提到的方向和目标,怎么结合百度自己的架构落地呢?首先,回顾下百度的架构,如下图 3 可以看到。

  1. 这里有两块日志,意味着同一套代码要在两个部分维护;除了重复之外,它们的差异会对后续的维护引入更高的成本;
  2. 底层这个 HHVM+PHP 和社区更加拥抱 Node.js 会有冲突。

所以,百度同学把目标架构调整为图 4 所示。

图 4 中可以看到:

  1. 把日志、搜索框、相关搜索、性能打点等独立成单独的模块,有专门的同学来独立维护和迭代;
  2. 在前后端之间加了一层渲染层;让业务代码和后端的逻辑分开;
  3. 在底层加了 Node.js 机制。

目标、方向都解决好之后,就得看如何实施。对于一个小体量的库来说,从零构建架构就行;但是对于百度来说,实施也是难点。不仅要考虑平滑迁移、性能不退化,还要考虑长期可维护性、安全性、跨平台等。

前文也提到了,基本思路是按照基础设施、模块拆分、组件化的步骤执行;基础设施是业务模块划分的关键,完善的自动化和工具链是模块化的前提;模块化拆分可以为业务和团队提供更好的横向扩展能力;模块化的基础上,可以进一步在模块内部建设组件化方案来加速业务迭代。

在基础设施需要关注的事情包括:

模块化拆分需要关注的事情包括:

注意:

模块化拆分不是技术问题,而是业务问题。只有根据业务和产品进行垂直划分,才有可能达到解耦和独立迭代的目的。否则只是形式上拆分耦合的代码,会造成更大的维护和沟通成本。

由于组件是业务模块内部的选型,组件化的方案相对比较自由。只需要不严重影响性能,且能够平滑过渡即可。

Part4四、落地方案

1. 模块化

具体的落地方案,我们也用一张图(图5)来表示。可以看到它分为服务端和浏览器端两部分。

2. 服务端

百度是把整个大模块拆分成多个独立业务模块,最终页面由模块组合而成。这要求业务模块具有统一的接口,即上图所示的 Molecule 接口,它定义了模块如何渲染、有哪些依赖等信息。因为渲染过程封装在了模块内部,所以整个架构可以支持多语言、多框架。

相信你也发现,Molecule 和微服务非常相似。它们的关键区别在于,微服务的服务之间通过 IPC 互相操作,且每个服务可以独立伸缩、独立部署;而 Molecule 的各模块存在于同一个进程里。虽然有这样的区别,Molecule 仍然可以实现和微服务近乎相同的特性,如图 6 所示。

图 7 展示的是一个具体的业务模块的服务端入口文件,其中 ToptipController 是实现了由 Molecule 提供的控制器接口;这个接口要求提供一个渲染函数,接受一个字典类型的数据,返回渲染之后的页面内容。由调用方决定如何组装页面。

如上是业务模块提供方的接口。此外 Molecule 机制还为调用方(组装最终页面的那一侧)提供了方便的接口,可以在需要引入子模块的地方,传入子模块名称和参数即可在运行时渲染出来。整个机制的原理很简单,但实际使用中可能还需要引入命名空间、考虑模块版本等问题。

3. 客户端

那么客户端如何运行起来呢?我们也需要把每个模块的浏览器端组件运行起来,困难在于组件之间的依赖和代码共享。这些组件可能位于不同的代码库并属于不同的业务,所以我们需要一个非常松散的依赖方式。

这里我们引入的是一个依赖注入的容器(图 8),总的来说,框架逻辑和通用工具都封装成具体的Service提供给业务模块使用,每个业务模块则需要定义它依赖于哪些Service。

图 9 形象地描述了组件、Service 和容器间的关系。

其中蓝色代表具体的Service,其他颜色表示独立的业务模块。运行时容器会负责解决每个业务模块的依赖,并把这些业务模块组装起来,最终得到可交互的 Web 页面。

注意:

业务模块之间是独立的,一个业务模块无法依赖于其他业务模块,只能依赖于通用 Service。因此如果存在业务模块之间的产品逻辑耦合,可能需要一个通用 Service 作为媒介,比如容器里提供一个起事件总线作用的 EventService。

图10是业务模块的客户端代码示例。它的依赖通过构造函数来声明,运行时容器负责依赖的创建,而业务模块只需要关心依赖的使用。正是使用和创建操作的分离,使得业务模块之间、业务模块和页面框架之间可以解耦,可以独立地开发、独立地测试。

以上是模块拆分的整体方案,我们回顾一下:在服务端通过一个叫做 Molecule 的接口来组合业务模块;在浏览器端通过一个 DI 容器来解决依赖关系,并启动所有业务模块。

4. 组件化

组件化方案直接影响业务开发的的效率,换句话说,组件化方案某种程度上决定了业务同学写怎样的代码。组件化也可以帮助解决职责不清晰等问题。我们选的组件化方案是 San,你也可以基于你的业务或偏好选则 Vue 或者 React。业务代码的迁移比较直观,就是从 Smarty 模板迁移到 San 组件,从 HTML 字符串拼接变成有业务语义的组件结构。

接下来重点关注组件化方案的两个关键技术问题,跨平台和页面性能。

1. 跨平台

我们有非常多的业务代码,有上千个模板、几十万行代码,这些代码需要迁移到组件化方案上来,而且要确保后端从 PHP 迁移到 Node.js 的整个过程中,业务代码不需要重新开发。所以业务组件如何跨平台呢?关键在于抽象。

做到以上几点就可以完成平滑的过渡。这个过程中又分为三个阶段(图 11)。

2. 页面性能

引入前端框架通常意味着体积增加,性能下降,而性能直接影响搜索收入,因此页面性能是项目成功的关键。如果性能会比模板引擎的性能差,那么这个项目很可能会夭折。如何去保证页面性能?着重介绍两个优化点。

引入***。为了解释***的重要性,请看图12。浏览器加载页面分为四步:请求页面、请求外链资源、执行脚本、渲染组件。从图中的对比可以看出,CSR在前面三步的时候,用户都是看不到页面的;而引入***之后,在第二步用户就能看到请求回来的页面。***它最大的一个用途就是提升首屏时间。

*** 优化。只是引入 *** 还不能让性能达到预期,因为相比于模板引擎直接拼接字符串,*** 需要递归渲染组件,尤其是递归 VNode 比较耗时。对此 San *** 相比于 Vue/React *** 做了很多改进。

图 13 展示了最终的 San *** 和改造前的 Smarty 模板引擎的性能对比。

可以看到 Smarty 和 San *** 在不同的场景会有不同的表现,因为它们的渲染方式非常不同。最终搜索结果页的组件化的 *** 上线之后,线上实验效果显示比 Smarty 要快 10ms左右。这个已经是一个很不错的效果了,我们用组件化从性能上打败了模版引擎。

Part5五、结语

针对百度搜索引擎在架构演化中遇到的问题,相信在其他领域也会有一些共性的东西。通过百度的解决思路,希望能对正在做前端架构的你有一些启发。

 

来源:晨曦大前端内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯