谢朴老师邀请。
利益相关: egg 团队成员,jsconf china 2016 的 egg topic 的演讲者。
本文较长,包含以下内容,比较忙的同学可以跳阅:
- Node.js 在阿里的定位
- 我们面对的挑战与机遇
- egg 在阿里的定位 / 发展史 / 开发者
- egg 的设计理念和特点介绍
- 我个人在参与 egg 开发过程中的收获
1. Node.js 在阿里
阿里是业界最早的一批使用 Node.js 来做线上大流量应用的公司,早在 2011 年的就已经开始在生产环境中使用。
众所周知,在阿里的技术栈中, Java 是最最核心的,那 Node.js 扮演怎么样的一个角色呢?
- 基础设施大部分采用 Java/C++ 实现,变化较少,有事务要求的 Business Services 通常使用 Java 实现。
- 而 Node.js 则替代过去 PHP/Java Web 的场景,用在需要快速迭代,需求变化非常快的用户侧。
据不完全统计,目前阿里 Node.js 的开发者几百号人,线上的应用也非常之多,仅次于 Java 应用,光对外服务的进程数就超过 1w+。
2. 我们面对的挑战与机遇
Node.js 的使用是越来越多了,但整个基建和生态却跟不上:
- Node.js 开发者越来越多,但是真正涉足基础技术的人员还是那么少,那么分散。
- 出现非常多的重复性技术问题和重复建设,每个团队一套轮子。
- 非常多不合理地使用 Node.js 进行 Web 开发,也没有一套统一的规范可以参考。
- 越来越多的 Node.js 应用出现,需要保证高可用。
面对上述的挑战,阿里的 Node.js 先驱者们,做了非常多的探索和努力,如:
- 朴灵的 alinode 就是一套运行时环境和服务平台,帮助开发者分析性能问题,快速定位疑难杂症。
- 苏千的 cnpm / tnpm 提供 npm 国内镜像加速服务,以及阿里内部私有库服务。
- 死马等很多同学贡献的几百块个 Node.js 基础类库,还有各种服务的 Node.js 版 sdk。
- 还有包括整个工作流程上的内部系统和工具支撑,阿里的 Node.js 基建真的很不错。
- node 的 collaborator 有 5 个国人, 其中 4 个在我们这边.
也正是因为他们一代代的努力,Node.js 在阿里才能落地生根,才有今天这繁荣。
对这块有兴趣的同学,可以开个问题邀请苏千/死马等人讲讲他们当年在阿里的开荒史。
3. egg 在阿里的定位
egg 也是这一时代洪流中的新生一员,它面向的领域是:企业级的 web 基础框架
。
- 2013 年蚂蚁的 chair 框架,可以视为 egg 的前身。
- 2015 年 11 月,在苏千的召集下,阿里各 BU 的前端骨干齐聚黄龙,闭门共建。
- 2016 年初,各 BU 的基础 web 框架完成升级,在同一套规范的基础上进行差异化定制。
- 2016 年中,广泛使用在绝大部分阿里的前端 Node.js 应用。
- 2016 年 09 月,在 JSConf China 2016 上亮相并宣布开源。
- 2017 年初,官网文档 https://eggjs.org/ 亮相,并发布 egg@1.0 版本。
egg 目前是阿里 Node.js 应用的核心基础设施,担心是 KPI 产物的同学,可以放宽心了。
有哪些人参与到 egg 的开发和维护中?
- 核心开发者中,贯高(popomore, 小 substack),苏千(Python发烧友),死马等人,是开源社区的资深人士,每个人维护的 npm 模块都有几百个,同时也是 cnpm 和 koa 的核心开发者。
- 我们甚至还有 2 位前端安全方向的专家,负责 egg-security 等类库。
- 阿里各 BU 的前端活跃开发者,光框架和插件的维护者就超过 40 位。
- 外部开发者也不少,甚至还有几位硅谷华人开发者在帮我们翻译文档。
同学们也不用担心 egg 只适合阿里或电商类应用:
- 蚂蚁金服,天猫,UCWeb,村淘,神马等 BU 的业务场景千差万别,但他们的基础框架都是在 egg 之上扩展的,遵循的是同一套规范。
- egg 的设计机制,使得我们在遵循同一套规范的同时,完美的达成生态共建和差异化定制的平衡点。
- egg 里面只有我们对企业级应用的最佳实践,而并没有耦合任何阿里的具体业务逻辑。
4. egg 的设计理念
Think about future, Design with flexibility, But only implement for production.
4.1 约定优于配置
一个大规模团队的基础框架,最重要的是需要遵循一定的约束和约定。
没有约定的团队,沟通成本是非常高的,比如有人会按目录分栈而其他人按目录分功能,开发者认知不一致很容易犯错。通过约定可以减少开发人员的学习成本,开发人员不再是『钉子』,可以流动起来。
egg 最核心的东西,其实就是一套约定和规范,这个规范不仅仅是开发目录的约定,还包括了开发过程中,从提案讨论,编码风格,code review 等等方方面面的规范化。
其实大家的基础框架用不用 egg 真的无所谓,最重要是有一套适合团队的约定。
egg 给社区最有价值的回馈是:
- 源于我们在大规模企业级应用中的经验沉淀,它们的产出物就是各种约定和插件。
- 我们的文档,包含了非常多的框架设计思路,即使你不用 egg,也可以看看,如:
- 然后就是类似 egg 团队这种基于 gitlab/github 的硬盘式协作模式,以及在 issue 中的各种讨论,后来的开发者可以轻而易举的了解某个设计思路的前因后果。
当然,我们推荐基于 egg 来定制上层框架:
- egg 采用微核 + 插件体系,本身大部分功能由插件提供,高度灵活,功能强大。
- egg 提供了完善的加载机制实现 - loader,也是整个框架的灵魂,并且支持非常多的扩展方式。
- 约定不等于扩展性差,相反 egg 有很高的扩展性。
- 对于团队架构师或技术负责人,它足够的 optional,只需简单的做加法,组装插件即可。
- 对于团队开发人员,它又足够的强约束,保证不会出现千人千面的代码风格和设计。
- 某种意义上来讲,egg 也是渐进式的框架,参见 egg 文档 - 渐进式开发。
4.2 插件机制
插件机制是 egg 的一大特色,它不但可以保证框架核心的足够精简、稳定、高效,还可以促进业务逻辑的复用,生态圈的形成。
经典范例如 egg-security,就集合了阿里集团的多年安全经验积累,具体可以看下 egg 文档 - 安全。
同时,差异化定制不意味着没有约定,它只是下层插件实现的差异化,而上层开发体验是一致的:
- 如 egg-view-nunjucks / egg-view-react 这类插件,遵循 模板插件开发规范 的同时,又不限制具体模板引擎选项。仅需安装不同的 view 插件, 上层开发体验是一致的。
- 如 egg 文档 - 插件 中提到的 mysql 等的实例化方式,只要是开发中共性的模式,都会被不断的总结和沉淀下来成为约定。
- egg-tracer / egg-userrole 这些约定,等等,无处不在。
4.3 框架机制
上面提到的插件机制,很灵活,但是对于企业级应用来说,却还不够。
如果你的团队遇到过:
- 维护很多个项目,每个项目都需要复制拷贝诸如
gulpfile.js
/webpack.config.js
之类的文件。 - 每个项目都需要使用一些相同的类库,相同的配置。
- 在新项目中对上面的配置做了一个优化后,如何同步到其他项目?
如果你的团队需要:
- 统一的技术选型,比如数据库、模板、前端框架及各种中间件设施都需要选型,而框架封装后保证应用使用一套架构。
- 统一的默认配置,开源社区的配置可能不适用于公司,而又不希望应用去配置。
- 统一的部署方案,通过框架和平台的双向控制,应用只需要关注自己的代码。
- 统一的代码风格,框架不仅仅解决代码重用问题,还可以对应用做一定约束,作为企业框架是很必要的。egg 在 koa 基础上做了很多约定,框架可以使用 Loader 自己定义代码规则。
为此,egg 为团队架构师和技术负责人提供 框架定制
的能力,框架是一层抽象,可以基于 egg 去封装上层框架,并且 egg 支持多层继承。
+-----------------------------------+--------+
| app1, app2, app3, app4 | |
+-----+--------------+--------------+ |
| | | framework3 | |
+ | framework1 +--------------+ plugin |
| | | framework2 | |
+ +--------------+--------------+ |
| egg | |
+-----------------------------------+--------|
| koa |
+-----------------------------------+--------+
这样,整个团队就可以遵循统一的方案,并且在项目中可以根据业务场景自行使用插件做差异化,当后者验证为最佳实践后,就能下沉到框架中,其他项目仅需简单的升级下框架的版本即可享受到。
4.4 质量保障和技术支撑
- egg 所有的核心代码和插件,都有 93+% 的覆盖率的单元测试。参见 egg 文档 - 单元测试。
- 规范的 github pull request 协作模式,每一次提交都会经过自动化集成测试,以及 2+ 个核心开发者的 review。
- 严格遵循 semver 版本发布规则,可以放心的使用
^
引入我们的模块。 - 提供了 egg-bin,npminstall 等等开发期的辅助功能,让开发者更愉悦的进行开发。
- 内网版的 egg 是继承于社区版的,大部分问题,我们能第一时间感知到并及时修复。
- 技术支撑方面,在前面第三节里面也提到了,我们有非常多且活跃的开发者,以及内部的广泛使用,并不会没人维护。
- node 的 collaborator 有 5 个国人, 其中 4 个在我们这边.
4.5 其他
与其他框架的对比
其实不是一个层面的,sails , hapi 这些框架,通过 egg + 对应的插件封装成上层框架,就一样了。
egg 与 koa 的关系
- koa 是一个非常优秀的框架,然而对于企业级应用来说,它还比较基础,而 egg 选择了 koa 作为其基础框架,在它的模型基础上,进一步对它进行了一些增强。
- egg 升级到 koa2 的成本?
- egg 的核心开发者即为 koa 的核心开发者
- 非常之低, 具体参见我们的升级计划
5. 我个人在参与 egg 开发过程中的收获
回顾这几年,我个人感觉是非常幸运的,13 年的时候,跟着云龙做前端工程化,15 年则是参与到 egg 的整个开发过程中。
在这旅途中,我熟悉了堪称教科书式的基于 Git Pull Request 的异步硬盘式协作模式;我学习到不少大规模应用中的经验总结;这一段经历让我受益良多,永远无法忘怀,在无数个大半夜,一帮人还在 issue 上讨论的热火朝天。
很幸运自己能参与到阿里的 Node.js 发展中搬一两块砖,这里的基建和生态真的非常完善:
- 私有库有苏千的 tnpm
- 性能分析有朴老师的 alinode (egg 开源前还用它发现了 node set header 提升 10x 速度的一个坑,对这个有兴趣的,开问题邀请朴老师回答吧~)
- 各种后端服务都有死马他们维护的对应的 SDK 接入
- 还有非常多的数据上报,监控等等工作流上的辅助工具和系统。
- 还有玉伯团队的三年规划,佩服到五体投地。
有好奇心的同学,在杭州的,不妨亲自进去看看,不信,你看叔叔 @徐飞 。
而在广州的同学,也可以过来 UC 这边体验下,我们的内部交流通道非常顺畅。https://www.zhihu.com/question/55271199/answer/143741434 。
最后,回过头来看,我个人是挺感慨的,这么短时间,完全没有政治命令,大家主动拥抱共建,对于阿里这样如此大规模的多部门的公司,真可谓奇迹。
国内的开发者真的不用妄自菲薄,这几年,越来越多的国内框架如 ant design,element,weex,macaca 等等,正走出国门,拥抱世界。
以上