AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

Lyft 如何将 100+ 前端微服务迁移到 Next.js

Andrew Hao,Josh Callender

  • 2021-03-06
  • 本文字数:2755 字

    阅读完需:约 9 分钟

Lyft如何将100+前端微服务迁移到Next.js

介绍

在 2019 年,Lyft 的前端架构需要一次梳理。我们的公司快速增长,新的团队每天都在开发新软件系统。那时,我们从一个服务生成模板来生成新的前端服务——用一个我们定制的零配置的前端构建平台。拥有这样一种简单的服务创建方法导致了新服务的爆炸性增长,这些服务使用基于 React 的前端框架构建的各种各样的代码。

 

与此同时,我们在尝试维护自己的前端平台(一组内部的 Webpack 配置、ESLint 库和框架代码)时遇到了一些不利因素,我们发现自己陷入了对隐藏的构建错误进行故障排除的困境,并且普遍发现我们的生产效率被此类支持请求所削弱。由于代码库开始分化(就像它们在微服务架构中一样),我们的开发人员发现升级到我们的前端平台的新版本的任务非常耗时且令人沮丧。

 

有 100 多个前端服务和几乎同样多的前端工程师,为了 Lyft 的增长,很明显我们需要做一些事情来确保我们的平台是可维护的。

我们存在哪些问题?


图片来源:ray rui on Unsplash

 

我们坐下来列举了我们面临的一些核心问题:

  • 分化的基础设施:新的平台版本并没有被统一应用。随着时间的推移,我们的前端基础设施开始分化,导致可维护性和代码复杂度问题。

  • 使整个服务群保持最新是非常难的:升级每项服务的责任落在我们的产品工程团队身上,他们通常很忙且超负荷运转。这导致服务在安全性和性能更新方面落后。

  • 基础设施的激增(和分化):每个服务根据自己的需求和团队偏好,以自己特殊的方式实现前端基础设施(如 Redux,或服务端渲染),导致通用应用程序模式的各种各样的实现。

  • 性能瓶颈:随着动态导入和其它打包大小优化等技术的推出,尚未升级到我们最新平台的前端服务,没有我们新的平台更新所带来的性能提升,会在性能方面落后。

  • 通用任务很难大规模应用:通常简单的任何很难大规模应用。例如,如果我们想要将styled-components引入到我们的包中,我们需要手动进入每个服务,根据每个服务的实现方法以其独特的方法来添加它。

  • 缺乏标准化:由于我们各种各样的代码库,共享代码是非常困难的。我们的工程师在实现模式和模块时必须重新发明轮子,而不是利用共享的代码和库。

迈向 Next.js


图片来源:https://github.com/vercel/next.js

 

我们决定转向开源社区来寻找一个内生的框架来解决这些令我们头疼的问题。在评估了不同的平台后,我们决定使用Next.js!我们喜欢:

  • 其内生的固执己见的理念,将有助于我们统一我们平台的不同架构。

  • 其可执行包装器,允许我们将所有中心应用程序关注点转移到模块接口后面,消除了我们维护自己的构建系统架构的需要。

  • 其强大的开源生态系统、友好的社区和可靠的文档,向我们展示了平台的未来发展和轨迹。

 

我们本可以直接拿来 Next.js,让每个人都按原样使用它,但我们还需要解决几个问题。

添加一点儿 Lyft 秘料…


图片来源:CHUTTERSNAP on Unsplash

 

开箱即用的 Next.js 存在两个问题没有解决。

首先,我们需要自动化未来平台迁移。

我们需要能够编写易于运行且稳固的服务升级,并能够大规模应用这些功能。为了解决这个问题,我们用jscodeshift设计了一个迁移服务,允许我们发布和运行迁移,在运行升级时自动更新服务代码。

 

这意味着,我们平台中任何未来的突破性变化都将伴随着自动化的代码模块,从而升级宿主应用程序中的代码。这也意味着,我们可以打开拉取请求来升级整个服务群,而无需产品工程的干预。

我们需要一种代码共享的方法。

我们希望构建一个可扩展的应用程序体系结构,允许开发人员编写插件,以尽可能少的配置或粘合代码,来引入不同的状态管理器和包。我们围绕Webpack Tapable设计了一个插件服务,允许我们的任何开发人员将共享的 Lyft 包注入到服务中间件和客户端 React 应用程序来实现我们生态系统中的不同任务——从 GraphQL 客户端、Mirage 模拟支持、UI 组件库到围绕规范和日志的共享库。

开发人员沟通是关键



一个人不能仅仅靠自己去升级 100 个服务——我们需要验证和了解我们产品工程团队的痛点,然后再致力于我们的设计。我们采访了公司各个部门的工程师,来了解他们在当前平台上的挑战和痛点,并收集有关我们的新设计能否解决这些问题的反馈。在我们的内部前端公会全体人员会议上,我们不断向团队更新新技术栈的进度。整个过程从头到尾都是透明的且以开发人员为中心的。

 

我们将我们的新平台命名为 @lyft/service,并确定了一小部分开发人员将参与平台里程碑发布的 alpha 测试。随着我们的平台不断成熟,我们将受众扩大到更大的团队,他们会聚在一起参加为期半天的迁移研讨会。做这些会议真的帮助我们建立了一个社区,团队协作来学习 Next.js 架构,相互帮助修复问题,并了解更多关于我们为什么做出设计决策的上下文。

Beta 测试以及一些与 React Router 相关的问题

我们遇到了一些障碍,这些障碍是在我们开始在 beta 阶段迁移服务之后才出现的。例如,我们假设可以将所有应用程序从React Router迁移到Next.js默认的基于文件系统的路由。然而,由于 React Router 在我们的服务中实现的非常具体的方式,我们发现几乎不可能轻松地对这些路由进行模块编码。我们没有从 React-Router 迁移,而是构建了一个功能来允许我们的工程师保留他们现有的 React Router 路由并每次一个路由地分次迁移到 Next.js 路由。

迁移工作如何进行?

到 @lyft/service 的迁移非常容易运行。服务所有者只需要调用一个命令:

$ npx lyftsrv upgrade

我们的代码模块开始工作并安全地升级代码。一旦迁移完成,大部分繁重的工作已经完成!

 

当然,每个服务所有者也必须解决一些零散的问题,比如:

  • 修复单元测试

  • 与新的 Next.js 路由集成(或者使用我们的 React Router 实现)

  • 升级可能需要手工干预的包(例如 mobx 或 Redux 的使用)

 

平均来说,从运行迁移脚本到结束零散的问题需要几天的时间。

结果

如今,@lyft/service 运行着我们近 40%的前端服务,而且我们正在加速采用它。

 

我们看到了这个新平台令人难以置信的反馈,包括以下优势:

  • 将开发反馈循环(从代码更改到浏览器更新的时间)减少了 350ms。

  • 将打包大小减少了 845kb(在我们的样本应用程序中)。

  • 从每个服务中删除了 10000 行基础设施代码

 

迁移到这个新平台将在未来继续得到回报,因为:

  • 新的升级与 NPM 模块升级 @lyft/service 并运行迁移 CLI 命令一样简单。因为基础设施代码完全封装在一个包(和一套插件)后面,所以迁移所涉及的面比过去少得多。

  • 迁移可以通过在整个服务群中自动打开的拉取请求自动完成,所需的产品团队干预要少得多,而且所有服务都可以接收到 Next.js 社区所提供的最新最全的更新。

 

有关迁移的更多详细信息,请观看Josh在Next.js 2020大会上关于我们的迁移过程的演讲

作者介绍

Andrew Hao lyft 和 carbonfive almni 工程师,Wejoinin 联合创始人,喜欢跑步,酷爱咖啡。

 

Josh Callender lyft 的 Web 工程师,酷爱电影,美食家,技术迷。

 

英文原文链接:

 

Changing Lanes: How Lyft is Migrating 100+ Frontend Microservices to Next.js

2021-03-06 12:002612

评论

发布
暂无评论
发现更多内容

刨根问底 Kafka,面试过程真好使

蔡农曰

Java kafka 面试 后端

MySQL 数据库索引技术原理初探

mylxsw

MySQL 数据库 索引 B树

python利用open3d可视化npy文件

Studying_swz

Python 11月月更

Python 操作 lxml库与Xpath

度假的小鱼

11月月更 Python 操作 lxml库 UI自动化例子

第六章TCP/IP——网络传输硬件设备

初学者

11月月更

架构--模块六作业

李某人

架构训练营

架构误区系列7:删除+更新的缓存刷新机制

agnostic

缓存

【Python 函数】-参数-返回值

度假的小鱼

11月月更 Python函数参数使用

【Python 函数】-嵌套使用,变量的作用域

度假的小鱼

11月月更 Python局不变量 Python全局变量

Java 字符串 split 的一个反直觉陷阱

mylxsw

Java 字符串 基础 陷阱

耗时3个月啃烂了这份Redis技术笔记,我成功上岸进了字节

程序知音

Java 数据库 redis java架构 后端技术

Alien Skin Exposure2023最新版下载

茶色酒

Alien Skin Exposure

Sentinel Go-揭秘[流量控制]的实现原理

柠檬汁Code(binbin0325)

源码 sentinel 熔断 限流 冷启动

Baklib知识分享|知识管理中常用的5种工具

Baklib

第七章TCP/IP——ARP网络攻击与欺骗

初学者

网络 11月月更

【设计模式】装饰者模式:以造梦西游的例子讲解一下装饰者模式,这也是你的童年吗?

游坦之

软件工程 设计模式 11月月更

一文弄懂Vue与Servlet的交互:让你的大学课设变得容易起来

游坦之

Vue axios 11月月更

整合Mybatis、Servlet、Mysql、Axios、Filter、Session写一个入门级项目:非常适合初接触JavaWeb的小白白来进阶

游坦之

MySQL mybatis javaWeb Servlet 11月月更

MongoDB 新手入门 - Aggregation

mylxsw

mongo database 入门教程

花一周时间,啃完这套京东架构师独家微服务笔记,成功面进字节

小二,上酒上酒

Java 负载均衡 编程 架构 SpringCloud

模块六作业 - 拆分电商系统为微服务

小虎

架构训练营

阿里P8大牛刷算法的正确姿态!女朋友再也不用担心我刷不动力扣了

小二,上酒上酒

Java 编程 算法 LeetCode

混沌工程之ChaosBlade利刃出鞘

柠檬汁Code(binbin0325)

混沌工程 故障注入 ChaosBlade Chaos Mesh

架构实战训练营模块6作业

atcgnu

数据结构分析_Inception_GNN_GCN

Studying_swz

人工智能 深度学习 11月月更

熬夜也要肝完的阿里内部面试官手册,吃透直接拿下大厂心仪offer

小二,上酒上酒

Java 数据库 架构 分布式 高并发

分布式技术难学?谷歌大神首发纯手撸ZK+Dubbo笔记,网友看完直呼NB

程序知音

Java zookeeper 分布式 java架构 后端技术

Linux 磁盘管理

梦笔生花

11月月更 Linux系统 Linux磁盘管理

【设计模式】适配器模式:攻敌三分,自留七分,以超兽武装的例子来谈谈适配器模式

游坦之

软件工程 设计模式 11月月更

MongoDB 新手入门 - CRUD

mylxsw

mongo database 入门教程

阿里高工内产的 SpringBoot 保姆级笔记,面面俱到,太全了

程序知音

Java spring springboot java架构 后端技术

Lyft如何将100+前端微服务迁移到Next.js_语言 & 开发_InfoQ精选文章