基于 Node.js 先后端分离的一点思考

hello~亲爱的看官老爷们你们好~有一段时间没写文章了,最近忙于为一个对内的数据可视化平台进行彻底的先后端分离。原来的项目是一个基于 Vue 的单页应用,重构后接入 Node 做为中间层,达到彻底的先后端分离。前端

因为项目相对简单,成本并非过高。下文将简单介绍一下使用的技术栈与分离后的收益,重点是对基于 Node 作先后端分离的一点思考。数据库

背景

大约是去年11月底入职新东家,接手一个仅 对内 的数据分析系统。新入职固然是但愿作出点成绩,在更改部分 UI 与优化部分功能以后,发现页面性能仍是比较低。排查后发现获取数据的接口没有缓存,也不是基于 RESTful 的,浏览器缓存彻底不起做用。期间也经历了后端修改接口,前端代码大面积修改的状况。json

基于后端同窗不熟悉前端机制,我也抱着方便往后搞事情的心态,在屡次滚地板以后,部门 Leader 赞成接入 Node 做为中间层。后端

技术选型

在肯定接入 Node 后,首先要作的就是技术选型。Node 通常就是在 ExpressKoaEgg 中选。在中间件的使用上,我的偏好 Koa ,于是只好和 Express 说再见了 。Egg 是在 Koa 上做了强约束,规定代码编写、目录结构等。浏览器

选型时我与前端 Leader 讨论了无数次,他认为 Egg 约束太多,扩展性较差,如若出现框架底层的 Bug 则难于处理,于是偏向于使用 Koa。这样的顾虑十分合理,然而对于如今的项目而言,不太可能有功能会超出 Egg 所提供的,反而 Egg 所提供的功能能为项目搭建与维护减小很多的成本。至于约束,我的认为这反而是一件好事,必定程度上解决了多人开发时代码的组织问题。缓存

考虑再三后,决定使用 Egg 做为 Node 的框架。安全

分离收益

因为项目不算十分复杂,接入的过程算是波澜不惊。惟一的麻烦是工期比较紧,于是分两步走:一期先接入 Node,全部页端请求原样转发 Java,返回的结果原样转发页端。二期对数据获取的接口进行整合与优化以提高性能。完成后收益仍是客观的,贴两张图展现下成果。数据结构

原来某页面的性能(全部请求都是 Post 的):架构

接入 Node 相同页面的性能(转为方法为 Get):框架

能够看到,不管是数据下载量仍是响应时间等指标,耗时均有下降。固然,这是创建在接入 Node 后我对接口进行了整合与缓存优化等措施后的对比。若是都是首次访问,公司内网 WiFi 环境下与原来的性能会有稍差一点,总体加载时间略高于 Java 直出50ms不到。也用过 Chrome 模拟弱网环境,耗时与 Java 直出基本一致。

并且开发体验上也比以前舒服得多,算是达到了接入 Node 前定下的目标:接入后在支持相同功能的状况下性能提升30%;在相同的开发时间内,完成相同的需求,但有更好的开发体验及更好的页端性能。

小结一下,前端的一切优化都是在模板与获取模板所需数据上进行优化,使用 AngularReactVue 等框架构筑的单页应用,解决了模板的问题,能够再也不让后端去动咱们的模板。可是获取所需数据仍依赖于后端,很多单页应用交互上已经足够复杂,若是还需维护一套复杂的获取与整合数据的逻辑,仍是十分头疼的。于是多接入一层 Node 处理数据的获取与整合,尽最大努力去优化页端的请求接口,让页端专一于交互,在条件成熟的状况下,是十分值得的。

思考

如若就为了推广 Node,本文应该是把上面的步骤写详细,小结完就该结束了,这和不少大佬的实践文章一致(固然我写得不够好~)。然而和两位 Leader 的讨论过程当中,感谢他们对 Node 技术抱有怀疑,提出了很多有意思的问题,结合我本身的思考,整理成提问形式呈现给你们。

为什么接入 Node 做为中间层,和公司现行的 PHP 有何区别?

没有区别!事实说,Node 能作的 PHP 同样能作。那么问题就转换为 Node 的意义是什么,为什么摈弃公司相对成熟的 PHP 方案而转向 Node

我认为后端服务主要是稳定为主,业务调整不会特别频繁。而对于前端而言,业务频繁调整简直司空见惯,若是先后端耦合在一块儿,频繁让后端发版不是可取之策。同时,先后端对数据结构的要求及对其控制的粒度也大不相同。写得好 PHP 的同窗不必定写得好前端,写得好前端的同窗不必定写得好 PHP。对于专业的领域,仍是应该由专业的人去作,让前端控制整个模板及模板依赖的数据,对提升项目质量有很大的帮助。说句玩笑话,后端就搞搞数据库,吐吐 json 就好,前端就拿一下数据,切切页面就好。

进一步而言,前端若要接入 SSR 之类的功能,Node 还真比 PHP 有优点得多,也算是为往后搞事情作铺垫吧。

接入 Node 后性能会有多大提升?

不必定有提升,甚至有降低。此问题是我一期完成以后,测试页端性能时发现的。测试时,Node 除了将全部的需求原样转发外,还加了协商缓存,然而响应时间却更慢了。

接入前(为 Post 请求):

接入后(为 Get 请求):

正常来讲,获取 10k 左右的数据时,协商缓存如若命中即返回 304,省略了下载的过程,理应更快的。经过打点,发现 Node 转发请求耗时额外增长 10ms 左右,然而在全公司内网 WiFi 环境下,总体下载时间不到 160ms。

于是引入 Node 不必定会有性能的提升,反而会由于多引入一层,而致使性能耗损。在对内的项目中或性能尚可的项目中,提升性能不足以成为接入 Node 的关键理由。换句话说,接入 Node 以后,在优化页端请求以前,并不可能为应用性能带来飞跃。

这个问题也算是我对 Node 态度转变的起点,开始从无脑支持接入 Node 到辩证地推敲,也引出以后的的问题。

接入 Node 有什么弊端?

前端的能力越强,意味着责任越多。例如以前多是 Java 作的安全防御,可能就会下沉到 Node 端,这对大多数前端同窗而已都是比较陌生的领域。

投入的成本与产出也是值得商榷的事情,毕竟 Node 再贴近前端,也始终是属于后端的领域。先后端思想不太同样,用前端的思惟写后端,极可能写出十分糟糕的代码,轻则影响性能,重则内存泄漏。接入 Node 层后它反而成为拖累,相信你们也不肯看见。

毕竟 Node 对于很多公司而言是比较新的领域。尽管可能知道接入 Node 好处很多,但如何接入,接入后它能作什么,你们可能比较模糊。如何花最少的代价,平滑地接入 Node 的同时,最大限度的复用现有架构,也是个很多的挑战。

既然如此,没有 Node 适用的场景吗?

有。正如前文所说,Node 的意义是在于让前端掌握模板与模板所依赖数据,不妨从这两方面去进行考虑。如若重 SEO 的同时,页面交互相对复杂,这时候接入 Node 做为中间层,我认为就是最佳实践。

其次是后端架构不断演变,开始转向微服务化以后,前端感到接口碎片化开始带来很多麻烦后,就应该考虑接入 Node 整合接口了。

总的来讲,何时接入 Node, 有点像何时引入 ReduxVuex。当你感受到麻烦后,只要你知道还有这个选项,天然而言地就会想到用它。

小结

综上所述,在如下场景中,我认为接入 Node 是最佳实践:

  • 重视 SEO 且交互复杂。
  • 后端微服务化,前端须要整合接口。
  • 前端主导的项目,须要用到最新技术,如 SSRPWA 等。

如若只是性能问题,引入 Node 不必定会有改善,须要根据实际状况进行分析。至于后端的接口设计太丑陋、返回的数据结构不符合前端使用等问题,在应用规模不大的状况下,其实都是能够和后端同窗进行沟通的,以此接入 Node 不必定是最佳的实践,须要好好思量。

可是,坚定反对只是由于现有架构比较熟悉而不肯改变,始终抱着错误的方案不去解决的作法,这绝对是舍本逐末。我始终认为,只要是对的事情,尽管过程再艰难,亦应该朝着对的方向前进。

以上是我的的一点浅见,感谢各位看官大人看到这里。知易行难,但愿本文对你有所帮助~谢谢!

相关文章
相关标签/搜索