写点什么

【得物技术】前端微服务

用户头像
得物技术
关注
发布于: 2021 年 03 月 14 日

简介

什么是前端微服务

“ 微前端 ”一词最早于 2016 年底在 ThoughtWorks Technology Radar 中提出。它将微服务的概念扩展到前端世界。当前的趋势是构建一个功能强大且功能强大的浏览器应用程序(又名单页应用程序),该应用程序位于微服务架构之上。随着时间的流逝,通常由独立团队开发的前端层会不断增长,并且变得更加难以维护。这就是我们所说的 Frontend Monolith(巨石前端)。

Micro Frontends 背后的想法是将网站或 Web 应用程序视为由独立团队拥有的功能的组合。每个团队都有自己关心和专长的不同业务或任务领域。一个团队具有跨职能,并且从数据库到用户界面,端到端地开发其功能。

但是,这个想法并不新鲜。它与“ 独立系统”概念有很多共同点。在过去,类似的方法被称为“ 垂直系统的前端集成”。但是 Micro Frontends 显然是一个更友好,更轻巧的术语。(引用资料 3)

Monolithic Frontend(巨石前端)*

Organisation in Verticals (垂直组织)*


适用场景

一般来说,有以下需求的项目可以考虑使用微服务:

  • 维护时间长

  • 维护人员多

  • 祖传代码迁移平滑

  • 在老项目中使用新技术

前两点描述的是项目的不可维护性,后两点描述的是技术的迁移升级成本。

那么,典型的场景,就是各大公司企业级的 ToB 项目了。

优点/价值

  • 技术栈无关主框架不限制接入应用的技术栈,子应用具备完全自主权。

  • 独立开发、独立部署子应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新。

  • 增量升级在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略。

  • 独立运行时每个子应用之间状态隔离,运行时状态不共享。

  • • 简单、解耦的代码库打包、热更新都会加速。

采用微服务的架构,最重要的一点,是解决遗留系统,在不需要重写原有项目的基础下,可以使用新的技术。

功能设计

微服务只是一个笼统的名称,一个被称为微服务的架构大致需要考虑以下功能,根据需求来选择不同的功能集合,再考虑实现。


实现微前端的方式

  • 使用 HTTP 服务器的路由来重定向多个应用

  • 在不同的框架之上设计通讯、加载机制

  • 通过组合多个独立应用、组件来构建一个单体应用

  • iFrame。使用 iFrame 及自定义消息传递机制

  • 使用纯 Web Components 构建应用

  • 结合 Web Components 构建

图中的 o 表示支持,空白表示不支持,-表示不受影响。

可用框架参考

Qiankun

Single-SPA

缺点

  • 传输内容变大重复的公共依赖,会导致最终文件体积变大。

  • 环境差异当开发环境和生产环境差异较大时,可能会导致问题,尤其是容器本身和其他微服务中的全局样式。

  • 运维和管理复杂性前端将会需要管理更多的仓库、工具、构建部署、更多的域。

业务价值

如果微前端只存在工程上的价值是不值得大张旗鼓去做的。 -- 张克军

  • 产品的组合能力

  • widget 的产品输出能力

具体的业务价值,视领域不同,可大可小。典型场景是云平台,期望是对不同用户提供产品的不同组合,那么微服务的提供的平台、产品的被集成能力就非常契合。

各厂分析实现

前言

由于前端微服务兴起并不久,市面上并没有统一的做法,实现效果、实现方式千差万别。就拿“是否支持不同技术栈”来说,阿里的 qiankun 视之为微服务的核心价值,而 爱奇艺 和 ThoughtWorks 的 mooa 实现中就没有考虑支持不同技术。

为了能更加清楚得分析使用场景和各中利弊,特别建立本文档,记录下各个实现的重点内容。

爱奇艺技术产品团队

目标

  • 框架与业务更加的解耦

  • 模块的独立部署、发布等提高迭代效率

效果

🔲 独立开发:需要奖容器和全部微服务一起启动

✅ 独立部署

🔲 独立技术栈:仅支持 vue

🔲 tree shake:手动将 Vue,Router,store,RenderPage 写到全局资源,通用模块注册为懒加载组件

✅ 环境隔离:

🔲 多个应用同时运行:同时只能运行一个

🔲 公用依赖:否

🔲 依赖冲突:否

🔲 集成编译:未知

实现/特点

  • 应用资源:每个应用自己打包生成 manifest,标注资源地址

  • 路由:统一使用全局路由,子模块的路由加载时合并入全局路由

  • 渲染页面:document.head 中插入 script,再主动调用 window.mp.render_home(‘#containerId’)来渲染页面

只支持同一版本的 vue,定制化程度非常高的方案,优点是相对简单,缺点是用处不大。

美团 用微前端的方式搭建单页应用

目标

合并多个业务成一个

效果

🔲 独立开发:需要奖容器和全部微服务一起启动

✅ 独立部署

🔲 独立技术栈

🔲 tree shake

✅ 环境隔离

🔲 多个应用同时运行:同时只能运行一个

🔲 公用依赖:否

🔲 依赖冲突:否

🔲 集成编译:未知

实现/特点

  • 容器提供了额外的功能 * 用户登录机制 * 菜单权限获取 * 全局异常处理 * 全局数据打点

  • 路由由三部分组成权限菜单树、导航和路由树

美团 大规模微服务通信框架及治理体系OCTO核心组件开源

阿里 qiankun开源方案

目标

  • 简单,像接入 iframe 一样容易

  • 解耦,技术栈无关

效果

✅ 独立开发:容器和业务无耦合,可以随意启动

✅ 独立部署

✅ 独立技术栈

🔲 tree shake:无

✅ 环境隔离:可选沙盒模式

✅ 多个应用同时运行:可选支持模式

🔲 公用依赖:否

🔲 依赖冲突:否

🔲 集成编译:否

实现/特点

  • 实现基于 single-spa

  • HTML Entry 接入方式:接入子应用像 iframe 一样简单只配置子应用的首页地址(m.poizon.com)根据地址来请求整个页面,从页面中提出 script 和 style 资源 script 通过 eval 来执行

  • 资源预加载配合 HTML Entry ,在空闲时候加载子应用的首页的 style 和 script, style 写入 html,script 放入缓存

  • 样式隔离:子应用之间的样式互不干扰

  • JS 沙箱:子应用之间的 全局变量/事件 不冲突 mount 生命周期时 proxy 劫持 windowunmount 生命周期时恢复 window 属性和被劫持的方法

  • prefetch 预加载 requestIdleCallback 时机请求所有注册的 app,匹配 style 和 script 资源,预先下载缓存

接入

  • 添加 package.json 的 name 属性,作为唯一标记,应用之间不重复

  • 打包出来的配置需要更改

  • 需要提供一个不带侧边栏(头)的版本

生命周期(简易)


后续

随着技术的更新发展,目前有越来越多的微前端方案出现了,例如基于 webpack5 联邦模块实现的EMP,允从独立组件组建和管理前端的 Bit,新的框架带来新的创意,让我们拭目以待!

引用

  1. 采用前端微服务架构 - luca mezzalira

  2. 微前端的那些事儿 - 知乎 ID: phodal

  3. 微前端 - Michael Geers

  4. 微前端 - Cam Jackson

  5. 可能是你见过最完善的微前端解决方案 - 知乎 ID: kuitos

  6. 微前端的核心价值 - 知乎 ID: kuitos


文|巧克力

关注得物技术,携手走向技术的云端


发布于: 2021 年 03 月 14 日阅读数: 49
用户头像

得物技术

关注

得物APP技术部 2019.11.13 加入

关注微信公众号「得物技术」

评论 (2 条评论)

发布
用户头像
需要奖(将)容器和全部微服务一起启动

需要奖容器和全部微服务一起启动

2021 年 03 月 22 日 11:05
回复
谢谢指正,我们会努力做的更好~
2021 年 03 月 25 日 13:38
回复
没有更多了
【得物技术】前端微服务