基于NodeJS的前端分离的思考与实践(1)全栈开发
序
为了解决传统Web开发模式带来的各种问题,我们做了很多尝试,但是由于前端和后端的物理差距,所有的尝试都是相似的。今天我们重新思考“前后”的定义,引入前端学生熟悉的NodeJS,尝试探索一种全新的前端分离模式。
随着不同终端(Pad/Mobile/PC)的兴起,对开发者的要求越来越高,单纯浏览器的响应风格已经不能满足用户体验的高要求,所以我们经常需要针对不同终端开发定制版本。为了提高开发效率,前端和后端分离的需求越来越受到重视。后端负责业务/数据接口,前端负责呈现/交互逻辑。我们可以定制和开发同一个数据接口的多个版本。
这个话题最近讨论的很多,阿里的一些BUs也在做一些尝试。经过长时间的讨论,我们团队决定探索一套基于NodeJS的前端分离方案。在这个过程中,有一些变化的理解和想法,记录在这里。我们也希望看到学生参与讨论,帮助我们提高。
1.什么是前端分离?
小组讨论开始,发现大家对前端分离的理解不一样。为了保证大家能在同一个渠道上讨论,首先要就什么是“前端分离”达成一致。
大家一致认为前端分离的例子是SPA(单页应用)。使用的所有呈现数据都是由后端通过异步接口(AJAX/JSONP)提供的,而前端只呈现。从某种意义上说,SPA确实实现了前端分离,但这种方式存在两个问题:
SPA类占WEB服务的比例很小。在许多场景中,存在同步/异步混合模式,SPA不能作为通用解决方案。在目前的SPA开发模式中,通常是按照呈现逻辑来提供接口的。有时候为了提高效率,后端会帮我们处理一些呈现逻辑,也就是说后端还是参与View层的工作,而不是真正的前后端分离。SPA式的前端分离是为了区别于物理层(认为只要客户端是前端,服务器是后端),这种分离方式已经不能满足前端分离的需求,我们认为职责划分可以满足我们目前的使用场景:
前端:负责视图层和控制器层。后端:只负责模型层、业务处理/数据等。为什么要这样分工,后面会继续讨论。
二、为什么要把前后端分开?
在这个问题上,于波的文章已经非常全面地解释了Web R&D模式的演变。让我们再看一遍:
2.1现有开发模式的适用场景
于波提到的几个开发模型都有自己的适用场景,没有一个能完全替代另一个。
比如以后端为主的MVC,在做一些同步展现的时候,业务效率很高,但是涉及到同步和异步页面的时候,和后端开发沟通起来就比较麻烦。Ajax是主要的SPA开发模式,更适合开发APP类型的场景,但只适合做APP,因为SEO等问题不容易解决,而且这种开发模式对于很多类型的系统来说太重了。2.2前后责任不清
在一个具有复杂业务逻辑的系统中,我们最害怕维护前端和后端混合的代码。因为没有约束,其他层的代码可能会出现在M-V-C的每一层,随着时间的积累,根本没有可维护性。虽然前后端分离不能完全解决这个问题,但可以大大缓解。因为身体上保证你不能这么做。
2.3开发效率
淘宝的Web基本上是基于MVC框架webx,这就决定了前端只能依赖后端。所以我们的开发模式还是前端写静态演示,后端翻译成VM模板。这种模式的问题就不讨论了,被吐槽了很久。直接基于后端环境开发也很痛苦,配置、安装、使用都很麻烦。为了解决这个问题,我们发明了各种工具,比如VMarket,但是前端还是需要写VM,而且依赖后端数据,所以效率还是不高。此外,后端无法摆脱对呈现的强烈关注,专注于业务逻辑层的开发。
2.4前端的限制
如果性能优化的空间只限于前端,我们往往需要后端的配合才能有火花。但是由于后端框架的限制,我们很难使用Comet、Bigpipe等技术方案来优化性能。
为了解决上面提到的一些问题,我们做了很多尝试,开发了各种工具,但是一直没有太大的改进,主要是因为只能在后端为我们划分的小空间里玩。只有真正把前端和后端分开,才能彻底解决上述问题。
三、如何将前后端分开?
如何做到前端分离,其实第一节已经有了答案:
前端:负责视图层和控制器层。后端:负责模型层、业务处理/数据等。
试想如果前端已经掌握了Controller,我们可以做url设计,可以根据场景决定是在服务器端同步渲染还是根据视图层数据输出json数据,我们可以轻松的做Bigpipe、Comet、Socket等。根据表示层的需求进行定制,使用模式完全由需求决定。
3.1基于NodeJS的“全栈”开发
如果你想实现上图中的分层,必然需要一个web服务来帮助我们实现后端之前所做的事情,所以就有了“基于NodeJS的全栈开发”这个标题
这张图看起来简单易懂,但是如果你没有尝试过,就会有很多疑问。
在SPA模式下,后端已经提供了所需的数据接口,可以控制前端的视图。为什么要增加NodeJS层?多加一层,表现如何?多了一层,前端的工作量会增加吗?再加一层,就多了一层风险。怎么破?NodeJS可以做任何事情,为什么是JAVA?澄清这些问题并不容易。下面我来说说我的理解过程。
3.2为什么要增加一层NodeJS?
目前主要以后端MVC模式开发,严重阻碍了前端开发效率,使得后端无法专注于业务开发。解决方案是让前端控制Controller层,但是在现有的技术体系下很难做到,因为不可能所有的前端都学习java,安装后端的开发环境,写VMs。NodeJS可以很好的解决这个问题。不学一门新语言,我们也能做以前做的事。一切似乎都很自然。
3.3性能问题
分层涉及到各层之间的沟通,肯定会有一些性能损失。但是,合理的分层可以明确职责,便于协作,这将大大提高开发效率。分层造成的损失当然可以用其他利益来弥补。此外,一旦决定了分层,我们可以通过优化通信方法和协议来尽可能地减少损失。
比如淘宝宝贝详情页静态后,还有很多信息需要实时获取,比如物流、推广等。由于这些信息在不同的业务系统中,前端需要发送5到6个异步请求来回填这些内容。有了NodeJS,前端可以在NodeJS中代理这五个异步请求,可以轻松的做Bigpipe。这一块的优化可以大大提高整个渲染效率。也许你认为在PC上发送5或6个异步请求是可以的,但是在无线端,在客户的手机上设置一个HTTP请求是非常昂贵的。通过这种优化,性能将提高数倍。
淘宝细节基于NodeJS优化。我们正在优化过程中。上线后我会分享优化过程。
3.4前端有工作量
比起切页/做演示,绝对是一个提升。但是在目前的模式下,有联合调试和沟通的环节,非常耗时,容易出现bug,维护困难。因此,虽然工作量会增加一点,但整体开发效率会提高很多。
此外,测试成本可以节省很多。之前开发的接口都是针对表示层的,所以很难写出测试用例。如果前端和后端分开,即使是测试也可以分开。一组专门测试界面,另一组专门测试UI(这部分工作甚至可以用工具代替)。
3.5如何控制增加节点层带来的风险?
随着Node的大规模使用,系统/运维/安全部门的同学一定会加入到基础设施建设中来,他们会帮助我们改善各个环节可能出现的问题,保证系统的稳定性。
3.6 Node什么都能做,为什么是JAVA?
我们的初衷是把前面和后面分开。如果考虑这个问题,就有点违背初衷了。即使用Node代替Java,也不能保证今天不会遇到职责不清等问题。我们的目标是层层发展,做到专业,专注于做专业的事情。基于JAVA的基础设施已经非常强大和稳定,它更适合做当前架构的事情。
第四,淘宝基于Node从前端和后端分离
上图为淘宝基于Node的前端分离分层,以及Node的责任范围。简单解释一下:
顶部是服务器,也就是我们常说的后端。对我们来说,后端是接口的集合,服务器提供各种接口供我们使用。因为有一个节点层,所以不需要限制它是什么类型的服务。对于后端开发,他们只关心业务代码的接口实现。服务器下面是节点应用程序。节点应用程序中有一层模型代理与服务器通信。目前这一层主要是理顺不同接口的调用方式,封装视图层需要的一些Model。而Node层可以轻松实现原有的vmcommon、tms(参考淘宝内容管理系统)等需求。由开发人员决定在节点层使用什么框架。但是建议使用express xTemplate的组合,前后都可以使用。大家决定如何使用Node,但令人兴奋的是,我们终于可以使用Node轻松实现我们想要的输出模式, JSON/jsonp/restful/html/big pipe/comet/socket/同步和异步,想做什么就做什么,这完全是根据你的场景决定的。浏览器层在我们的架构中没有改变,我也不想因为Node的引入而改变你之前对浏览器开发的理解。通过引入Node,我们只是把应该由前端控制的部分交给了前端。在这种模式下,我们有两个项目正在开发中。虽然还没有上线,但在开发效率和性能优化方面,我们已经尝到了甜头。
5.我们还需要做什么?
将Node的开发流程整合到淘宝现有的SCM流程中。基础设施建设,如会话、记录器和其他通用模块。最佳开发实践在线成功案例每个人对节点前端分离安全性能概念的理解……在技术上不需要太多的创新和研究,已经有很多现成的积累。其实关键在于一些流程的打开和通解的积累。相信随着更多的项目实践,这个项目会逐渐成为一个稳定的过程。
第六,“中途岛”
“基于NodeJs的全栈开发”的Node虽然很刺激,但是要把基于NodeJS的全栈开发变成一个稳定的、可以接受的东西,还有很长的路要走,而我们正在进行的“中途岛”项目就是为了解决这个问题。虽然我们刚开始不久,但我们离目标越来越近了!
版权声明:基于NodeJS的前端分离的思考与实践(1)全栈开发是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。