在线教育大前端架构演进之路

2022-06-29 14:47:10 浏览数 (1)

前段时间,本人有幸于在深圳GMTC大前端架构演进专场进行分享。其后应叶冉编辑邀请,总结了此次分享的演讲稿《腾讯在线教育大前端架构演进之路》。首先做一下自我介绍。我是来自腾讯的工程师 haige,于16年校招进入腾讯QQ浏览器,目前在腾讯在线教育部 IMWeb 前端团队工作。本文对前端团队的架构演进,以及探索团队研发效率的工程化建设,有一定的借鉴意义。

一、在线教育部业务简介

技术团队的发展依托于业务的成长,我目前所在的是教育行业。团队目前有三款教育产品,分别是ABCMouse、企鹅辅导、腾讯课堂。

ABCMouse 是少儿英语的产品,帮助少年儿童学习英语,进行互动式教学;

企鹅辅导 是 K12 全科教育产品的,帮助小学、初中、高中学生进行应试教育;

腾讯课堂 是成年人阶段的教育,比如考证、雅思、公务员这类辅助教学。

介绍完我们的业务产品,再简列举一下团队的前端技术栈图谱。我们的产品几乎覆盖了大部分常见的用户场景,比如 APP、小程序、PC、H5等。业务场景包含了电商的大部分场景,即面向 2B 的机构,也面向 2C 的学生。而我们的教学场景主要是以音视频为主,以及一些互动教学的场景,上面就是我们业务的前端常用技术栈展示。

业务的发展面临着非常多的挑战。对于开发来说,最直接的问题就是:技术提升、协作管理、梯队建设;后面着重介绍了团队技术栈过去几年是如何进行升级的,以及团队如何为了促进进行协同办公,衍生出的效率工具建设。

二、大前端架构演进历程

以上是团队过去几年发展的不同阶段。

依次为:从技术栈统一;组件化落地;APP 的业务动态化建设;服务中台化建设,以及目前正在探索的云端一体化。

业务提升效率最简单的方式就是:组件化!

组件化可以优化团队的效率,提升产品的质量。但是在实践过程中,业务也遇到了技术栈混乱的问题。

技术栈混乱是由多种原因造成的,每个团队可能遇到的历史背景都不同,比如业务合并,之前是不同的团队;再比如:随着业务的发展,行业的技术趋势发生了翻天覆地的变化,很多历史项目,必须面临着重构和升级。

我们团队同样也面临了这些问题,前端技术栈也比较繁杂,因此,我们决定下决心统一技术栈,这样才能方便代码的复用和技术的深耕以及统一升级。

我们废弃了 fis、ng 和 vue,专注在 webpack 和 react 。团队也因此在这两个技术方向上,产生了一些有技术沉淀的同学,可以解决我们的日常遇到的各种疑难问题。

统一技术栈之后,我们行了组件化的建设。组件化的落地相对提升了团队的开发效率,在协同上面也有一些帮助。由此可见,沉淀组件的过程,就是团队规范慢慢形成的过程。

1

在线教育大前端动态化建设

问题:如何解决 APP 实时性问题?

随着业务的发展,灵活多变的产品需求,尤其是实效性方面的诉求,产品对于APP 的动态化能力也产生了强烈的诉求。这便引出了架构演进的第一部分:客户端的动态化方案探索。

从时间线来看,业务使用了非常多的手段去适应产品需求,也在其中找到开发人员的价值。我们的 APP 是混合开发的。也就是说,上面的能力都有,只是分散在不同的业务模块。

客户端动态方案确实是一种选择,如果不是苹果的问题,客户端动态化早都可以实现了。这确实是商业问题。

优点:可以配置化更新;缺点:需要预埋,扩展性不够。

优点:动态更新,开发和维护成本低;缺点:跟 Native 比,存在性能问题

相信离线包方案每个团队都用过,在 4G 之前,以及弱网络的情况下,Hybird 还是一个很好的方案,但是在很多安卓手机上面,确实解析和执行 JS 的时间比较漫长,因此无法达到比较好的极致优化,但是也可以一定程度的优化了页面的响应速度。我们也上过一段时间的 PWA,但是由于浏览器存在白屏的情况,因此无奈的在客户端内下掉了。

React Native 在 Flutter出现之前,应该是最有影响力的跨端方案了。

他的优点:保持 JS 开发,渲染性能提升;缺点:不同平台有差异,需要兼容处理 ,代码健壮性不强,因此 crash 率略高。

现在它依旧是最成熟的跨平台方案。阿里的 weex 也是在此基础上衍生出来的。

17年 react 爆发了 License 的风险,集团对业务产生了担忧,因此团队也相应号召,投入到了跨平台方案的探索上。当时我们还在 SNG,联合了“空间”、“即通”的同学一起探索了 Plato 项目,并且在业务落地了。19年 930 之后 BG 重新划分,这个项目也就此破产了。很多时候技术探索裹挟在公司的战略的发展当中,产生非常多的不确定性。技术的长期发展不仅要面对技术本身的挑战,而且还存在着很多无法预知的风险和问题。因此,不变的只有变化本身。但是技术上的探索对参与其中的同学来说确实成长不少。

18年我们第一次参加 GDD,19年第二次参加 CDD,19年我们的业务就落地了 Flutter 的实践。Flutter的技术优点:性能媲美 Native,且多端渲染一致;缺点:不支持动态化,目前生态不如 RN,前端编写 dart,脱离前端 JS 生态。

为了满足产品快速迭代,团队在一期落地 Flutter 的时候,更多的是把 Flutter 作为 UI 技术,去抹平了 ios 和 android 两端的重复开发。因此,大量的使用了底层的客户端能力,做了传输层,抹平了 ios 和 android 的调用差异。

由于 Flutter 官方不支持动态化,又恰逢 Flutter to web 合并了 Master 版本,团队就尝试了 Flutter to web 的落地,并从中得出结论:目前这个版本的 to web并不适合追求性能的业务,反而适合非 C 端场景;可用,但是没那么好用;对于动态化得解决一些突发事件还是可以的。

总结一下动态化方案的探索,其实本质就是一个渲染方式的的变革。从浏览器渲染到客户端渲染,在到自研引擎的渲染。不要把 Flutter 理解为 skia 的渲染方案,它代表了一种新的趋势,它代表了自研跨端引擎的时代开始,也许未来成功的不一定是 Flutter 这项技术,但是很可能是这种 自研跨端引擎 的解决方案。

2

在线教育大前端的服务中台化建设

问题:如何提升业务体验?

问题的原因前面简单的提到过,是因为客户端渲染速度的问题,在部分 android 机器上面,页面的渲染性能存在很大的问题,主要是客户端加载和解析 JavaScript 的时间过长。此外,加上加载资源的网络耗时,页面很难达到秒开。因此,客户端渲染要向服务端渲染进行迁移。这便引出了我们的 Nodejs 服务体系建设。

在 nodejs 服务建设的分享中,这里选择了团队 Node 服务的基石 IMServer 跟大家进行案例探讨。

如上面的架构设计是 基于 hapi 和 插件封装了 IMServer 1.0 。每一台业务机器都只运行了一个实例 framework,这个实例是通过 PM2 进行进程管理,包括启动、重启、监控、日志处理等等。当用户请求过来的时候,PM2 将请求分配给不同的 worker 处理并返回响应。

每一个worker其实是非常重的,它都包含了 framework层 和 业务层这两部分。在业务初期,所有的 server 都共用一个 framework。这种设计在业务前期的确提升了开发速度和产品迭代速度。原因很简单,应用开始写的代码比较少,大家的代码都能公用,而且解决的问题,也差不多。在业务初期的时候,这套框架非常好的解决了替代 Java VM 直出的方案,以及优化团队研发模式,达到了提升开发效率的目的。

经过了一段时间的业务沉淀,IMServer 1.0 的设计的不足也慢慢突显出来了。由于不仅承担直出服务,转而实现部分业务逻辑,导致公用一个 framework 代码耦合度高;缺少合理的规范导致开发效率低;耦合性高导致一个服务出现问题,所有服务都会存在问题,因此,会有偶发雪崩的风险,因此决定升级 IMServer。

IMServer 2.0 基于 KOA 的洋葱模型的设计,所有的组件和功能,都可以用插件的形式嵌入进去。其中,imserver 是核心的入口,封装了 KOA 和一些常用的组件和中间件。而 imserver-core 是负责了进程监控 和 文件加载策略,也维护一个相对规范的开发模式,而 imsocket 是集成了 websocket 的能力;

IMServer-core :定位是当前服务的 —— 守护进程,负责管理worker:进行进程的异常捕获、异常退出、服务重启;检测 master 安全退出、定时的心跳检测,可以为业务 server 保驾护航; 

自动 Loader机制,加载指定目录文件,并自动将方法注入到 app 对象上,简化了应用流程,改变了业务频繁引入代码的重复性劳动,提升了开发效率。收敛了引用路径,也为未来无损重启的热更新,也铺平了道路。

基于 IMServer 2.0 团队衍生出了很多技术中台,这里举例了如 管理后台、活动运营平台、基于 GraphQL 的 API 服务、 页面直出服务 SSR、以及消息推送中台 IMPush。

随着技术领域的拓展,前端开发者依旧面临了诸多的挑战,如运维的压力。那恰逢其时,serverLess 的到来,正好可以缓解前端遇到的困境。

我们先看下serverless: 无服务器架构,触发器,函数实例,调用后端服务。当云函数平台接收到触发函数的事件时,将会启动一个容器来运行函数代码,如果此时接收到了新的事件,并且上一个容器还在处理上一个事件,平台则启动第二个函数实例来处理第二个事件。其实不要解释的那么复杂,一言以蔽之,就是 让前端远离运维的无服务的设计,利用函数用完即走的设计思路,解决业务中遇到的问题。

这里对比了传统的 Node 服务和 serverless 的区别,本质上都是在 Nodejs 的 runtime 上运行,但是 serverless 的触发器跟多样性,在原有的 nodejs runtime 上进行一些改造。因此我们也进行了一些业务适配和微小的改造。通过 @tencent/serverless-imserver 可以让现有的基于 IMServer 的服务,无缝得迁移到新的 serverless 服务当中。

因此,基于 Nodejs 和 组件化的建设,衍生出了在线教育大前端架构的全景图。最上层是业务演进。下层的左侧是诊断能力,业务定位问题和发现的时机和效率是团队能力的核心指标。想做好一个团队,现网问题的反馈是否能优先于用户是很重要的指标。下层的中间包含了业务、组件、中台、运行环境的,是支撑业务快速发展的基础能力,正式由于他们的存在,才能让业务跑得快、蹦得高!

3

在线教育大前端研发效率工具演进

从需求开发的角度来看,这其中包含很多重要阶段:需求的提出、评审、宣讲;设计和产品达成一致,完成 1.0 的 demo 原型;给到 PM 和 开发 Leader 申请资源,决定开发时间和排期。这中间会经历产品内容的 PK 和 技术方案的设计和架构演进的思考。进入开发阶段,需要对齐协议、技术方案、项目里程碑、而后进入开发、联调、测试阶段;完成之后,产品体验、UI 走查、BUG 修复,而后是灰度、发布、全量。

我这里只是概述了从想法到目标的过程,这其实是一个非常复杂得系统性的工作流。现在的团队是产品提完需求,开发主导整个开发流程,需要需求 owner 对整体需求的进度有一个比较好的掌控,带领十个人参与完成开发时间长达几百人日的需求,owner 确实压力也不小。

通过参与并完成了一些业务实践之后,我这里给出一些不成熟的小建议:

  • 技术方案出来之后:建议开发给产品讲一遍实现,以免遗漏核心功能;
  • 开发最开始的时候:各端对齐开发协议(接口、字段),解耦开发;
  • 里程碑时间点确定:联调、提测、发布时间点排期,各端留好 Buffer;
  • 产品进入体验过程:大型需求很容易出现不一致的地方,甚至随着开发,会存在各种需求变更的场景。因此尽量的拆分项目,需求内部拆分多个里程碑的节点,让产品和设计尽早介入体验,尤其是产品上面还是有领导的情况下,很容易出现供需关系的不一致。这个时候控制不好节奏,开发会越来越心累。这个因团队而异,自己根据实际情况把握好节奏。当然,还需要注意的是,过早的介入也存在把开发时间切的很碎的弊端。
  • 增量需求注意适配:注意向上兼容,注意缓存、CDN、离线包场景的用户,协议扩展,以及发布顺序、外网运营等等。

好,进入正题,开发阶段 —— 本地开发、接口联调、测试发布,我们要如何提速!

本地开发阶段,需要有一个比较好的脚手架进行业务开发,以帮助开发者提升开发体验,以上四点是我对 CLI 工具的理解。团队内也孵化了像 IMFlow 这样的脚手架工具,帮助我们一站式的解决前端开发体验的问题。

CLI 工具的落地,可以让开发更聚焦于业务,感谢 json、eden、enjoy 同学。

前端是只是软件开发体系的一部分,不是团队整体的开发效率,因为,还有客户端、以及后台工程师。那么,接口协议的风险,联调风险,是否可以前置,减少沟通成本和反复重复的劳动,就是在提升效率。

托尔斯泰就是这样的一套工具 (http://tolstoy.oa.com/)。完成了接口数据的录入、CGI 的 MOCK、以及简单的数据获取和测试能力。在业务实践过程中,解耦开发的方式,会发现协议先行,会让接口联调时间节省 1/2 --> 2/3 左右的时间。

感谢 青杨、wooye 过去的实践。

调试本身,还是绕不开的。那么依旧存在很多上面的问题。如何解决呢?

团队基于 whistle 衍生了 Nohost 这样的工具!

 whistle 应该大部分同学都用过,不介绍了。

nohost 还是挺好用的,当然,替代方案也很多。但是,我依旧很喜欢。https://github.com/nohosts/nohost 大家可以找 aven 接入。感谢 aven、佳伟、特仑苏、land 过去一段时间的投入

在测试阶段、使用 tapd 进行 BUG 单的状态管理,减少了沟通成本,方便了后续统计,用数据说话很重要。企业微信内的小机器人,也还忙好用的,定期提醒、数据统计和输出,减少了人力成本。在整体流程上,在核心业务我们接入了 QTA 的自动化测试。感谢 theoxli、shijisun、wentliang、方杰 等同学的贡献。

测试之后是发布,发布出现问题的情况,我个人认为是非常多的。操作异常、不规范、发布冲突等等,需要靠流程保证发布成功率,为业务保驾护航。因此,我们拆解了发布周期中的核心路径,设定了打怪升级的关键节点。通过机器简化发布过程的重复劳动,通过流程保证发布的质量。

感谢 erasermeng、cover、eden、homer 过去一段时光的付出。

产品发布之后,如何进行动态运营是一个复杂而系统的工程。很开心过去一年取得的成绩。除了靠研发的责任心之外,还需要有工具盒方法帮助大家一起完成质量建设。数据上报 --> 数据统计 --> 量化考核 --> 快速响应!

工具只是手段,选择什么,用什么其实都可以,目标是解决问题!这里要感谢所有的小伙伴,质量的提升离不开每一个人的付出,这是大家共同的成绩。

研发流程是一个非常有意思的事情,深入体会它之后,就会发现团队有很多痛点需要去解决。我在刚来到团队的时候,就喷过一次研发规范, 还好领导都不是小气的人,没把我开除,今天回头再看过去写的东西,确实很多都是浆糊!此后,经过 2 年的迭代,所有人都取得了很大的进步,经历还是一件有意思的事情。

这里抽象一下,提升效率和质量的手段,在我理解就是规范和工具。

规范:会让团队变得更专业,并且朝着工业化的时代走下去 —— 形成技术架构体系!

工具:会让团队变得更高效,并且朝着智能化的时代走下去 —— 形成研发流水线!

三、总结与展望

团队发展的架构演进,就如上面这张图:统一技术栈 --> 组件化 --> 研发效率工程化 --> 服务中台化 ---> 云端一体化!所有的事情,其实都是并行的。并不是非要串行的一个接一个的进行处理。您团队当下最需要的事情,就是您要解决的事情。在我看来,先活下去,才能活的更好,危机意识导致了求生欲,饥渴的存在,才会让人变得更热血。

中台已经被讲了太多,这张图跟大家分享一下我们的前端中台是怎么样的!前端的复杂度和前端的系统性已经朝向一个更加适应前端成长的环境发展了,我很庆幸遇上了这么好的时代。能做的事情更多了,无论是传统前端,还是多端,或者业务后台,再如数据处理机器学习,前端的跨度如今就是整个软件开发体系。

边界已经在过去几代人的不停努力下,不断地被打破了。因此我们的价值才能被扩大!今天有产品的地方,就要有前端的存在!这里不是说,开发非要是前端开发,而是指前端思维,如何更好得面向产品,面向设计,面向用户的思维方式。在体验化和可用性上面,有了更多深入的理解和思考。

提升体验和优化性能最好的手段就是新技术的引入。值得注意的是,新技术的投资上面,要因地制宜。针对不同类型的业务和产品,选择不同的方式。这里罗列了一些在教育场景下,未来可能要去花时间投入的技术点。当然,在商业社会,技术只是手段。为了追求利润和价值,我们可以选择合作或者购买的方式,进行业务引入。用尽量科学的方式接入,解决业务问题,为产品创造价值,是业务开发的核心。当然对于工具类产品,性质可能就不尽相同了。选择适合自己的方式去解决问题和创造价值,是技术人员的核心能力之一。

我理解的团队规模:小型团队 10个人以内;中型团队 20 --> 50人;大型团队 100 --> 200人。我这里总结了几个必要条件,作为中型团队能够持续发展下去的基本目标。大部分场景下的业务团队,很少有 100个人 以上的前端规模,基本上都是维持在 50个人以内的中小型团队。那么,上面三个基本观点,支撑了我对于这样的团队,能够长久的持续发展的基本要求。

左侧团队公众号,右侧我的微信,欢迎交流

研发流程是一个非常有意思的事情,深入体会它之后,就会发现团队有很多痛点需要去解决。我在刚来到团队的时候,就喷过一次研发规范, 还好领导都不是小气的人,没把我开除,今天回头再看过去写的东西,确实很多都是浆糊!此后,经过 2 年的迭代,所有人都取得了很大的进步,经历还是一件有意思的事情。

全文总结

“作为 web 开发者,技术的平稳期已经到来了,2019年也是一个新阶段的开始,我们也可以展望一下未来一段时间的 Web 技术的发展。大环境随着人口红利的结束,All In 移动的时代也慢慢结束了,多端并行的时代正式的开始了。更多注重产品实际体验的打磨,专注细节开发。

从技术角度, PWA 已经进入了平稳期,后面会是基础能力的补齐,比如 Push、离线化。而在桌面应用 NW、Electron 也会逐步侵蚀掉传统客户端开发的领域,既省时,又省力,并且可以统一技术栈。今年开发者大会并没有提及 WebAssembly,但 wasm 在确实是可以让 WebGl 和音视频在未来有更多的发展空间。跨端领域对于 Flutter 未来的发展依旧非常看好,它也许就是下一个 Chrome,是移动端跨平台的终极解决方案。语言层面 TS 、Dart、Go 也都进入了前端开发的视野。最后,不得不提的三大框架 和 小程序,在向着标准化和 web Components 看齐。

看似繁荣的前端世界,有太多眼花缭乱的选择,确实是一件有趣的事情。这是一个盛世时代,还是虚假繁荣,亦或开发者的自娱自乐,您自己评判!”

上面这段话引用一下自己在曾经写过一段评价:『2019 年谷歌开发者大会参与感』 。确实前端技术发展,已经到了相对稳定并且陡峭爬坡得状态。更专注在垂直领域的深耕,比如 VR、AR、音视频;再如,横向领域跟客户端方向的多端融合,RN、Flutter 的持续发展;亦或者,跟后台领域类似的微服务架构的设计、serverless,等等。

众多的技术体系也标致着今天做一个应用的成本越来越容易了,支撑海量服务的成本越来越低了,对技术开发者的综合能力的要求也发生了很多的变化。API Boy 这个词,会是很多人未来新的标签,甚至已经被挂在了现在很多人的身上。如何找到价值,如何提升价值,如何创造新的价值是我们未来每一个开发同学需要思考的问题。

这里明确了是开发,不是前端开发!我预计未来几年之后,所有的应用开发,没必要在区分前端、客户端,或者后台,大家都是软件开发工程师。随着工程师的能力提升,边界会被继续的打破,组织会更加扁平化。

我的预感是:业务产品支撑的开发会更加精简,基层的去中心化的架构会逐渐形成。

未来会对普通用户更善良,对技术本身更敬畏,对开发同学更尊重。

IMWeb 团队隶属腾讯公司,是国内最专业的前端团队之一。

我们专注前端领域多年,负责过 QQ 资料、QQ 注册、QQ 群等亿级业务。目前聚焦于在线教育领域,精心打磨 腾讯课堂、企鹅辅导 及 ABCMouse 三大产品。

扫码关注 腾讯IMWeb前端团队

0 人点赞