前言为了解决传统web开发模式带来的各种问题,我们做了很多尝试,但是由于前后端物理上的差距,尝试过的解决方案是相似的。痛定思痛,今天我们重新思考“前后端”的定义,介绍前端同学耳熟能详的NodeJS,尝试探索一种新的前后端分离模式。随着不同终端(Pad/Mobile/PC)的兴起,对开发者的要求也越来越高。单纯的浏览器端响应已经不能满足用户体验的高要求。我们经常需要为不同的终端开发定制版本。.为了提高开发效率,前后端分离的需求越来越受到重视。后端负责业务/数据接口,前端负责展示/交互逻辑。我们可以自定义开发同一个数据接口的多个版本。这个话题最近讨论的比较多,阿里的一些BU也在做一些尝试。经过长时间的讨论,我们团队决定探索一套基于NodeJS的前后端分离方案。过程中有一些变化的认识和思考,记录在这里。也希望看到的同学能够参与讨论,帮助我们改进。1、什么是前后端分离?最初在群里讨论的时候,发现大家对前后端分离的理解都不一样。为了保证讨论能够在同一个频道进行讨论,首先要就什么是“前后端分离”达成共识。大家比较认同的前后端分离的例子就是SPA(Single-pageapplication)。所有使用的显示数据都是由后端通过异步接口(AJAX/JSONP)提供的,前端只做显示。从某种意义上说,SPA确实实现了前后端分离,但是这种方式存在两个问题:在WEB服务中,SPA类所占的比例非常小。很多场景下,存在同步/同步+异步混合模式,SPA不能作为通用的解决方案。在目前的SPA开发模式下,通常是根据展现逻辑来提供接口。有时候为了提高效率,后端会帮我们处理一些表现逻辑,也就是说后端仍然参与View层的工作,并不是真正的前后端分离。SPA式的前后端分离是从物理层上区分的(以为只要客户端是前端,服务端就是后端),这种划分已经不能满足了我们对前后端分离的需求。我们认为只有通过职责划分才能满足我们目前的使用场景:Front-end:负责View和Controller层。Backend:只负责Model层,业务处理/数据等,为什么做这样的职责划分,后面会继续讨论。2、为什么要分离前后端?关于这个问题,余波在Web研发模式演进的文章中解释的很全面。我们再来看一下:2.1现有开发模式的适用场景余波提到的几种开发模式都有各自的适用场景。哪个完全取代了另一个。比如基于后端的MVC做一些同步展示的业务是非常高效的,但是遇到同步和异步的页面,跟后端开发沟通起来会比较麻烦。基于Ajax的SPA开发模式比较适合APP类场景的开发,但是只适合APP,因为SEO等问题不好解决,而且对于很多类型的系统来说,这种开发方式太重的。2.2前后端职责不明确在一个业务逻辑复杂的系统中,最怕维护的是前后端混杂的代码。因为没有约束,其他层的代码可能出现在M-V-C的每一层。久而久之,根本就没有可维护性了。单词。前后端分离虽然不能彻底解决这个问题,但是可以大大缓解。因为你这样做在身体上是不可能的。2.3开发效率问题淘宝的Web基本是基于MVC框架webx,架构决定了前端只能依赖后端。所以我们的开发模式还是前端写静态demo,后端翻译成VM模板。这个模式的问题我就不说了,被吐槽了很久。直接基于后台环境开发也很痛苦,配置安装使用都很麻烦。为了解决这个问题,我们发明了各种工具,比如VMarket,但是前端还是要写VM,依赖后端数据,效率还是不高。另外,后端也不能摆脱对表现的强烈关注,从而专心于业务逻辑层的开发。2.4前端性能优化的局限性如果仅仅前端空间非常有限,我们往往需要后端配合才能产生火花。但是由于后端框架的限制,我们很难使用Comet、Bigpipe等技术方案来优化性能。为了解决上面提到的一些问题,我们做了很多尝试,开发了各种工具,但是一直没有太大的改进,主要是我们只能在后端分配给我们的小空间里玩。只有真正做到前后端分离,才能彻底解决上述问题。3、如何分离前后端?前后端如何分离,其实在第一节就已经有了答案:前端:负责View和Controller层。Backend:负责Model层,业务处理/数据等。试想,如果前端掌握了Controller,我们就可以做url设计,我们可以根据场景决定在服务端同步渲染,或者根据视图层数据输出json数据,我们也可以轻松做Bigpipe、Comet、Socket等,完全由需求决定。3.1基于NodeJS的“全栈”开发如果要实现上图的分层,就必须需要一个web服务来帮助我们实现后台之前做了什么,所以才有了“基于NodeJS的全栈”《开发》标题中提到的《NodeJS》看似简单易懂,但如果你没有尝试过,你会有很多疑问。在SPA模式下,后端已经提供了需要的数据接口,前端已经可以控制视图了。为什么要添加额外的NodeJS层?添加一个额外的层怎么样?多加一层,前端的工作量是不是增加了?多加一层就多一层风险,如何破解?NodeJS无所不能,为什么是JAVA?把这些问题解释清楚并不容易。说说我的理解过程吧。3.2为什么要加一层NodeJS?现阶段主要开发后端MVC模式,严重阻碍了前端开发的效率,导致后端无法专注于业务开发。解决方案是让前端控制Controller层,但是在现有的技术体系下很难做到,因为不可能所有的前端都学习java,安装后端开发环境,以及写虚拟机。NodeJS可以很好的解决这个问题。我们不需要学习一门新的语言,我们可以做以前开发帮助我们做的事情,一切都显得那么自然。3.3性能问题分层涉及到各层之间的通信,肯定会有一定的性能损失。但合理的分层可以明确职责,便于协作,会大大提高开发效率。分层带来的损失一定能够弥补其他方面的收获。此外,一旦分层确定,我们可以通过优化通信方式和通信协议,尽可能减少损失。例如:淘宝宝贝详情页静态化后,还有很多信息需要实时获取,比如物流、促销等,因为这些信息在不同的业务系统中,所以前端需要发送5或6个异步请求来回填这些内容。有了NodeJS,前端就可以在NodeJS中代理这5个异步请求,轻松做Bigpipe。这种优化可以大大提高整体渲染效率。也许你觉得在PC端发送5、6个异步请求还可以,但是在无线端,在客户端手机端创建一个HTTP请求是非常昂贵的。通过这个优化,性能可以一下子提高好几倍。基于NodeJS的淘宝详情优化正在进行中,待上线后分享优化过程。3.4前端工作量有没有增加?比起只切页面/做demo,肯定是多了一点,但是现在的模式,有联调和交流环节。这个过程耗费大量时间,容易出现错误,并且难以维护。因此,虽然工作量会增加一点点,但是整体的开发效率会大大提高。此外,还可以节省大量的测试成本。之前开发的接口都是针对表现层的,很难写测试用例。如果前后端分开,连测试都可以分开。一组人专门测试界面,另一组人专注于测试UI(这部分工作甚至可以用工具代替)。3.5如何控制增加Node层带来的风险?随着Node的大规模使用,系统/运维/安全部门的同学肯定会加入到基础设施建设中来。他们会帮助我们改进各个环节可能出现的问题,保证系统的稳定性。3.6Node无所不能,为什么还需要JAVA?我们的初衷是前后端分离。如果我们考虑这个问题,那就违背了我们的初衷。即使用Node代替Java,也不能保证不会出现今天遇到的各种职责不明等问题。我们的宗旨是分层发展,专业的人,专注做专业的事。基于JAVA的基础设施已经非常强大和稳定,更适合现在的架构。4.淘宝的Node-based前后端分离上图是我对淘宝Node-based前后端分离分层的理解,以及Node的职责范围。简单说明:最顶端就是服务器,也就是我们常说的后端。对于我们来说,后端就是接口的集合,服务端提供了各种接口供我们使用。因为有Node层,所以不需要限制服务的形式。对于后端开发,他们只使用关心业务代码的接口。服务器下方是Node应用程序。Node应用中有一层ModelProxy来与服务器进行通信。这一层主要是为了打通我们调用不同接口的方式,封装视图层需要的一些Model。Node层也可以轻松实现原有的vmcommon、tms(指淘宝内容管理系统)等需求。由开发人员决定为Node层使用什么框架。不过推荐使用express+xTemplate的组合,前后端可以共享xTemplate。Node怎么用就看大家了,但令人兴奋的是,我们终于可以用Node轻松实现我们想要的输出方式:JSON/JSONP/RESTful/HTML/BigPipe/Comet/Socket/synchronous,asynchronous,随心所欲如何修复它完全取决于您的场景。浏览器层在我们的架构中并没有发生变化,我们也不想因为Node.js的引入而改变大家之前对在浏览器中开发的认识。Node的引入,只是把应该由前端控制的部分交给了前端。我们已经有两个项目正在以这种模式开发。虽然还没有上线,但在开发效率和性能优化方面我们已经尝到了甜头。5.我们还需要做什么?将Node的开发流程整合到淘宝已有的SCM流程中。基础设施建设,如session、logger等常用模块。***开发实践上线成功案例大家对Node前后端分离概念的理解安全性能...技术上没有太多创新和研究的必要,已经有很多现成的-做了积累。其实关键是一些流程的打通和通用方案的积累。相信随着更多的项目实践,这会逐渐成为一个稳定的过程。6.《中途岛》虽然“基于NodeJS的全栈开发”模式很精彩,但是要将基于Node的全栈开发变成稳定的、被大家接受的东西,还有很长的路要走。正在进行的“中途岛”项目旨在解决这个问题。虽然才刚刚开始,但我们离目标越来越近了!!
