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

一、被误解的前后端分离

在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版本以及快速流程实施框架等功能组件的开发。

本文分享自微信公众号 - EAWorld(eaworld)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-11-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

nwui —— 又一个go语言图形界面解决方案

Github: https://github.com/go-nwui/nwui 最近开的一个大坑,具体实现就是自动生成htm+css+js然后调用nw.js来显...

29630
来自专栏张戈的专栏

SendCloud邮件队列状态和已使用额度的Python监控脚本

公司最近用上了 SendCloud 的邮件代发服务,于是就有了各种监控需求。比如每天发信额度是不是要超标了或是邮件是否堵塞了等等。最近经常接触 python,所...

42490
来自专栏张戈的专栏

分享几个可用的二维码API,以及给博客添加文章二维码图片的方法

最新补充:博客已分享性能最好的 js 生成二维码方案==>传送门 今天发现之前用的二维码 API 不怎么稳定了,老是出现图裂无法加载的情况。用的是 api.qr...

69840
来自专栏云计算D1net

让云API远离黑客攻击

没有合适的安全措施,云API就会成为黑客的一扇门。那么如何确保云API的安全呢? 开发者可以使用云应用编程接口编码,而这个接口具备一项云提供商的服务。但是同时对...

43760
来自专栏张戈的专栏

分享张戈博客自用的php网址在线转换二维码的API源码

最新补充:博客已分享性能最好的 js 生成二维码方案==>传送门 去年张戈博客曾分享过一篇与二维码 API 有关的文章:《分享几个可用的二维码 API,以及给博...

41930
来自专栏Golang语言社区

Go语言开发Windows应用

当第一次看到Go程序在windows平台生成可执行的exe文件,就宣告了windows应用也一定是Go语言的战场。Go不是脚本语言,但却有着脚本语言的轻便简单的...

64560
来自专栏云计算D1net

如何避免陷入意外的“云锁定”窘境

鉴于云仍然处于其发展的初期阶段,云服务供应商之间的竞争依然十分激烈。因此,云服务成本在不断地下降,而其功能与性能则在不断得到提升。其结果就是,众多云项目规划者都...

31270
来自专栏Golang语言社区

问题帖子--Concurrent Read/Write Map

DK1.5 引入了 concurrent package, 提供了更多的concurrent 控制方法。 还提供了一个 ConcurrentHashMap 类...

378120
来自专栏张戈的专栏

WordPress发布文章自动同步到新浪微博(带特色图片)

WordPress 发博客后自动同步到新浪微博,这是我从无主题博客看到的方法,一直沿用至今。感觉对博客宣传和提升“逼格”都有显著的作用: ? 一、老版代码 先来...

57870
来自专栏张戈的专栏

Linux系统date命令无法修改或同步时间的解决办法

今天,在站长交流群里面,又一个站长抱怨服务器每星期都必须手动重启一次,否则 QQ 登陆功能无法使用,原因是服务器时间快了 5 分钟以上,腾讯服务器拒绝提供 AP...

47540

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励