前后端分离,是为了彼此更好


 2016-12-07 14:44:01       1239

转载本文需注明出处:EAII企业架构创新研究院(微信号:eaworld),违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群 姓名 公司 职位 微信号”。


一、被误解的前后端分离


在Web应用开发过程中,业界对前后端的分界线似乎一直都没有确定的概念,不过大多数人以浏览器作为前后端的分界线。将浏览器中为用户进行页面展示的部分称为前端,而将运行于服务器,为前端提供业务逻辑和数据准备的所有代码统称为后端。


虽然前后端分离在数年前就已经开始受到关注,但很多人对它却是只闻其声,未见其形,所以对它产生了一些误解,误以为前后段分离只是一种Web应用的开发模式,只要在Web应用的开发期进行了前后端开发工作的分工就是前后端分离。


其实并非如此,准确的说,前后端分离并不只是开发模式,而是Web应用的一种架构模式。在开发期,前后端工程师可以通过约定好交互接口,实现并行开发;在运行期,前后端分离模式需要对Web应用进行分离部署,前后端之间使用HTTP请求进行交互。然而作为应用的架构模式,前后端分离并不是通过这样一句话就能一概而谈的,我们可以从交互形式、代码组织方式、开发模式三个方面对前后端分离进行认识。


1、交互形式

在前后端分离架构中,后端只需要负责按照约定的数据格式向前端提供可调用的API服务即可。前后端之间通过HTTP请求进行交互,前端获取到数据后,进行页面的装配和渲染。


2、代码组织方式


在传统架构模式中,前后端代码存放于同一个代码库中,甚至是同一工程目录下。页面中还夹杂着后端代码。前后端工程师进行开发时,都必须把整个项目导入到开发工具中。


而前后端分离模式在代码组织形式上有以下两种:


半分离

前后端共用一个代码库,但是代码分别存放在两个工程中。后端不关心或很少关心前端元素的输出情况,前端不能独立进行开发和测试,项目中缺乏前后端交互的测试用例。

分离

前后端代码库分离,前端代码中有可以进行Mock测试(通过构造虚拟测试对象以简化测试环境的方法)的伪后端,能支持前端的独立开发和测试。而后端代码中除了功能实现外,还有着详细的测试用例,以保证API的可用性,降低集成风险。


3、开发模式


传统的MVC架构开发,没有进行前后端分离,前端工程师负责编写HTML,完成前端页面设计,然后给后端工程师员套界面,使用模板技术将前端代码转换成JSP页面,同时内嵌java代码。应用运行期,将全部代码进行打包,部署到同一服务器上,或者进行简单的动静态分离部署。


此时,应用的开发流程如下图所示。



在前后端分离架构中,前端工程师只需要编写HTML、js、CSS等前端资源,然后通过HTTP请求调用后端提供的服务即可。除了开发期的分离,在运行期前后端资源也会进行分离部署。


前后端分离之后,开发流程将如下图所示。


通过上面的两幅流程图,不难发现,在开发模式上,前后段分离不仅仅只是工程师的分工开发,更重要的意义在于实现了前后端的并行开发,和简化了开发流程。



二、为什么要“离”:4个好处



重新认识前后端分离之后,想必大家心里都会有疑问,前后端分离模式与之前的Web应用架构相比可谓是大相径庭,我们为什么要进行前后端分离呢?正如莎士比亚在《哈姆雷特》中的经典名句一样,分还是不分,这是个问题。


从目前应用软件的发展趋势来看,一方面,用户越来越注重软件的体验感,随着互联网的蓬勃发展,应用开始走向多终端化;另一方面,大型应用的架构模式正纷纷向着云化、微服务化发展。


虽然过去的应用架构暂时还能支撑起当下应用的开发,但是各种弊端已经开始浮出水面,几年前能带来开发便捷优势的前后端代码混合模式,在当下已经成为了拖慢我们前进步伐的泥沼,让我们屡屡吃痛。我们之所以开始尝试前后端分离,是为了能在未来获得更好的发展,期望通过前后端分离架构,来为我们带来以下4个方面的提升。


为孵化优质产品打造精益团队


正如康威定律所述,产品是组织沟通结构的缩影,软件开发团队想要孵化出优质的产品,必须先打造一个精益的开发团队。开发团队的组织划分是如何影响产品的孵化呢,我们通过下面的示例来进行说明。


如果开发团队是按照业务边界进行划分的,开发出来的产品将可能会是微服务的架构。



如果开发团队分为前端团队、后台服务团队和DBA团队,产品将会成长为下面的架构。



应用不断迭代,功能日趋完善,开发团队也随之壮大。虽然现在有些人比较推崇全栈工程师,一位全栈工程师就能支持前后端的所有开发。但是试想一下,如果在开发团队中前后端开发分隔不清,职责边界模糊不明,代码均由相同的工程师完成,长此以往前后端代码的耦合程度可想而知。


通过将开发团队前后端分离化,让前后端工程师只需要专注于前端或后端的开发工作,使得前后端工程师分别自治,培养其独特的技术特性,然后构建出一个全栈式的精益开发团队。这样的开发团队能够快速应对需求的变更以及市场的复杂多变,打造出架构清晰、前后端并重的优质产品。


提升开发效率


传统开发模式中,前后端开发强依赖。需要前端工程师先完成静态页面的Demo,后端工程师才能将页面Demo翻译成VM模板,如果前端页面出现变动,又会需要前后端工程师再走一次开发流程,如此一来开发效率将会变得很低。


前后端分离以后,可以实现前后端代码的解耦,只要前后端沟通约定好应用所需接口以及接口参数,便可以开始并行开发,无需等待对方的开发工作结束。与此同时,即使需求发生变更,只要接口与数据格式不变,后端开发人员就不需要修改代码,只要前端进行变动即可。如此一来整个应用的开发效率必然会有质的提升。


完美应对复杂多变的前端需求


Web应用的用户体验关注度与日俱增,使得应用的前端界面需要有华丽酷炫的外观,简单易用的操作,变化多样的界面设计和个性化的自定义展示。这使得前端开始变重,逻辑复杂程度加大,渲染效果多样化加剧。


移动终端的大范围普及,让应用向着多终端化发展,这就要求前端页面需要对不同终端的显示都能进行配适。


传统开发模式中,前后端工程师开发职责不明确,面对复杂多变的前端需求,开发团队势必会变得捉襟见肘、不堪重负。


如果开发团队能完成前后端分离的转型,打造优秀的前后端团队,开发独立化,让开发人员做到专注专精,开发能力必然会有所提升,能够完美应对各种复杂多变的前端需求。


增强代码可维护性


前后端分离后,应用的代码不再是前后端混合,只有在运行期才会有调用依赖关系。应用代码将会变得整洁清晰,不论是代码阅读还是代码维护都会比以前轻松。




三、我要不要“离”:4种场景



然而任何一项技术都不是银弹,前后端分离也是如此。虽然前后端分离架构能带来众多优势,但终究得建立在开发团队适合的基础之上。我们暂且以前端页面的渲染效果与逻辑复杂程度把Web应用大致分为轻前端、重前端、前后均衡三种类型,然后加上现在热门的微服务架构应用,一起探讨一下什么样的Web应用适合进行前后端分离。


轻前端

页面布局简单,颜色、字体类型较少

对前端界面的渲染效果没有高要求,无动画效果

只有少量、简单的业务逻辑

只需要在不同终端上布局能适应


对于这样对前端渲染要求不高,业务逻辑简单的轻前端应用来说,因为涉及到的前端技术并不复杂,所以没必要追求前后端分离。将前后端代码放到一起,反而更方便进行开发,但是在开发过程中需要做到关注点分离(Separate Concern)。


重前端

页面布局复杂,使用了多种颜色和字体

需要有较高的页面渲染效果,有大量动画

前端页面中包含有复杂业务逻辑

需要在不同终端和浏览器上保证布局适应和渲染效果


对于重前端应用,建议采用前后端分离架构,如果开发团队中前端工程师不足,需要尽早完善前端团队的建设,确保前后端并重。


前后均衡

页面布局适中,使用的颜色和字体种类不多

页面中使用了少许动画效果

业务逻辑较为简单,可下沉到后端实现

只需要在不同终端上布局能适应


对于前后端均衡应用,建议综合团队的人员结构和未来发展方向进行考虑。如果在团队中前端工程师的占比不高,后续也没有继续发展前端的计划,那么就不建议过于追求前后端分离。如果对未来有更高期望,即使在前端工程师占比不高的情况下,依然建议团队尝试前后端分离转型,开始着手培养合适的前端工程师。如果团队中已经有了相当规模的前端工程师,建议立即转向前后端分离,并且尽早做到前后端代码分离,为前端提供一个可以进行开发调试的伪后端。


微服务架构应用



微服务架构应用由大量微服务提供者构成,共同为用户提供服务。在微服务架构中,很多微服务提供者都是基于SpringBoot实现的,通过API Getway(API网关)进行微服务的整合,然后在一个统一的前端门户上为用户提供所需服务。


微服务基于SpringBoot开发,要达到快速交付的目的,并且每个微服务的粒度都比较小,这必然需要微服务的前后端由不同的工程师分别实现,然后相互之间使用Restful进行通讯。如果还是沿用之前的开发模式,将会增大微服务架构应用的构建难度。而前后段分离模式正是解决这一难题的良药。



四、分离部署方案浅析


前后端开发分离之后,应用在部署时也需要进行前后端分离。在进行前后端分离方案选择的时候,需要结合项目的需求情况和用户群体来考虑。目前业内较为常用的前后端分离部署方案有如下几种。


1、Nginx+Server


将前端资源部署在Nginx上,后端服务部署在常规的服务器。当浏览器发起访问请求的时候,如果请求的是页面资源,Nginx直接把资源返回到前端;如果请求是调用后端服务,则经过Nginx转发到后端服务器,完成响应后经Nginx返回到浏览器。



这个方案比较简单,易于实现,而且能达到前后端解耦的目的。


但是对于页面量比较大,需要有良好SEO的应用来说,此方案缺点也较为明显。因为Nginx只是向浏览器返回页面静态资源,而国内的搜索引擎爬虫只会抓取静态数据,不会解析页面中的js,这使得应用得不到良好的搜索引擎支持。同时因为Nginx不会进行页面的组装渲染,需要把静态页面返回到浏览器,然后完成渲染工作,这加重了浏览器的渲染负担。


2、Node+Server


这是淘宝所使用的前后端分离模式,在浏览器与后端服务器之间增加一个了Node Server作为中间层,将前端资源部署到Node Server中。Node Server中还包含了一层Model Proxy,负责与服务端进行通信。


浏览器发出的请求都被Node Server接收,然后通过Model Proxy调用后端服务器提供的服务。Node Server得到后端服务器反馈,接着在Node Server中完成页面的组装渲染,把最终页面返回给浏览器。


如此一来不仅达到了前后端解耦的目的,还解决了浏览器渲染负担过重的问题,为SEO提供了比较好的支持。


但在这样的模式中,浏览器所有发出的请求都需要经过Node Server进行中转,然后才能到达后端服务器。在实际的应用中,并不是所有的请求都需要页面渲染,只要在页面上直接调用后端服务器提供的服务即可。所以这个模式必然会对请求性能有所消耗


3、Nginx+Node+Server


为了能解决方案2中请求性能损失的问题,我们可以考虑在其基础之上增加Nginx。浏览器发起的请求经过Nginx进行分发,URL请求统一分发到Node Server,在Node Server中进行页面组装渲染;API请求则直接发送到后端服务器,完成响应。


目前在已经有一个名为Goku的Go语言框架提供了这样的前后端分离解决方案。



通过对三种前后端分离方案的对比可以看出:


如果是企业级应用,不需要考虑对SEO的支持,浏览器渲染也可以忽略不计,Nginx+Server的模式无疑是最好的选择,实施成本相对来说比较低;


如果是互联网应用,需要有良好的SEO支持,页面渲染工作量大,那应该选择Nginx+Node+Server的方案,各个方面都能得到比较好的兼顾。



五、总结


前后端分离并非仅仅只是前后端开发的分工,而是在开发期进行代码存放分离、前后端开发职责分离,前后端能够独立进行开发测试;在运行期进行应用部署分离,前后端之间通过HTTP请求进行通讯。前后端分离的开发模式与传统模式相比,能为我们提升开发效率、增强代码可维护性,让我们有规划地打造一个前后端并重的精益开发团队,更好地应对越来越复杂多变的Web应用开发需求。


传统的前后端混合开发模式,虽然久经考验,到现在依然还是能支撑起应用的开发。但是放眼未来,应用的云化、微服务化势不可挡。同社会分工精细化一样,前后端开发的精细化也是必然趋势。技术在持续进步,架构在不断演进,只有紧跟发展的脚步,不断调整项目管理方式,软件开发模式,才能在互联网浪潮中把握机会,乘风破浪。


前后端分离,是为了让彼此更好。



关于作者

敖显奇

现任普元信息SOA产品部开发工程师,普元新一代数字化企业云平台开发团队成员,参与云平台中VCS、Portal Server领域系统开发。过去两年中参与了普元 Platform产品 7.3~7.5版本以及快速流程实施框架等功能组件的开发。

关于EAII

EAII(Enterprise Architecture Innovation Institute)企业架构创新研究院,致力于软件架构创新与实践,加速企业数字化转型。


eaworld项目(微信号:eaworld,长按二维码关注)

eaworld是EAII的官方微信账号。

相关阅读: