为什么要前后端分离
MVC 开发模式
在介绍前后端分离前,我们来回顾一下在进行 Java web 项目开发时所选择的开发模式,在初学 Java web 开发时,我们通常选择的是 JSP + Servlet 来完成前端视图和后端业务逻辑的开发,这种开发模式属于 Model1 模式,虽然实现了逻辑功能和显示功能的分离,但是由于视图层和控制层都是由 JSP 页面实现的,即视图层和控制层并没有实现分离。随着学习的深入以及开始渐渐熟悉企业应用开发,我们渐渐的摈弃这种技术选型,并开始在项目中使用了若干开源框架,常用的框架组合有 Spring +Struts/Spring MVC + Hibernate/Mybatis 等等,由于框架的优越性以及良好的封装性使得这套开发框架组合迅速成为各个企业开发中的不二之选,这些框架的出现也减少了开发者的重复编码工作,简化开发,加快开发进度,降低维护难度,随之而火热的是这套技术框架背后的开发模式,即 MVC 开发模式,它是为了克服 Model1 存在的不足而设计的。
MVC 的具体含义是:Model + View + Controller,即模型+视图+控制器,
Model 模型层: 它常常使用 JavaBean 来编写,它接受视图层请求的数据,然后进行相应的业务处理并返回最终的处理结果,它负担的责任最为核心,并利用 JavaBean 具有的特性实现了代码的重用和扩展以及给维护带来了方便。
View 视图层: 代表和用户交互的界面,负责数据的采集和展示,通常由 JSP 实现。
Controller 控制层: 控制层是从用户端接收请求,然后将请求传递给模型层并告诉模型层应该调用什么功能模块来处理该请求,它将协调视图层和模型层之间的工作,起到中间枢纽的作用,它一般交由 Servlet 来实现。
同时,项目开发在进行模块分层时也会划分为三层:控制层,业务层,持久层。控制层负责接收参数,调用相关业务层,封装数据,以及路由并将数据渲染到 JSP 页面,然后在 JSP 页面中将后台的数据展现出来,相信大家对这种开发模式都十分熟悉,不管是企业开发或者是个人项目的搭建,这种开发模式都是大家的首选,不过,随着开发团队的扩大和项目架构的不断演进,这套开发模式渐渐有些力不从心,接下来我将结合我的自身经验来实际的分析这套开发模式的痛点。
知识点
什么是前后端分离
优劣势对比
痛点一:JSP 效率问题
首先,JSP 必须要在 Servlet 容器中运行(例如 tomcat,jetty 等),在请求 JSP 时也需要进行一次编译过程,最后被译成 Java 类和 class 文件,这些都会占用 PermGen 空间,同时也需要一个新的类加载器加载,JSP 技术与 Java 语言和 Servlet 有强关联,在解耦上无法与模板引擎或者纯 html 页面相媲美。其次每次请求 JSP 后得到的响应都是通过 Servlet 通过输出流输出的 html 页面,效率上也没有直接使用 html 高。由于 JSP 与 Servlet 容器的强关联,在项目优化时也无法直接使用 Nginx 作为 JSP 的 web 服务器,性能提升不高。
痛点二:人员分工不明
在这种开发模式下的工作流程通常是:设计人员给出页面原型设计后,前端工程师只负责将设计图切成 html 页面,之后则需要由后端开发工程师来将 html 转为 JSP 页面进行逻辑处理和数据展示。在这种工作模式下,人为出错率较高,后端开发人员任务更重,修改问题时需要双方协同开发,效率低下,一旦出现问题后,前端开发人员面对的是充满标签和表达式的 JSP 页面,后端人员在面对样式或者交互的问题时本就造诣不高的前端技术也会捉襟见肘。
在某些紧急情况下也会出现前端人员调试后端代码,后端开发人员调试前端代码这些让人捧腹的现象,分工不明确,且沟通成本大,一旦某些功能需要返工则需要前后端开发人员,这种情况下,对于前后端人员的后期技术成长也不利,后端追求的是高并发、高可用、高性能、安全、架构优化等,前端追求的是模块化、组件整合、速度流畅、兼容性、用户体验等等,但是在 MVC 这种开发模式下显然会对这些技术人员都有一定的掣肘。
痛点三:不利于项目演进
项目初期,为了快速上线应用,选择使用这种开发模式来进行 Java web 项目的开发是非常正确的选择,此时流量不大,用户量也不高,并不会有非常苛刻的性能要求,但是随着项目的不断成长,用户量和请求压力也会不断扩大,对于互联网项目的性能要求是越来越高,如果此时的前后端模块依旧耦合在一起是非常不利于后续扩展的。举例说明一下,为了提高负载能力,我们会选择做集群来分担单个应用的压力,但是模块的耦合会使得性能的优化空间越来越低,因为单个项目会越来越大,不进行合理的拆分无法做到最好的优化,又或者在发版部署上线的时候,明明只改了后端的代码,前端也需要重新发布,或者明明只改了部分页面或者部分样式,后端代码也需要一起发布上线,这些都是耦合较严重时常见的不良现象,因此原始的前后端耦合在一起的架构模式已经逐渐不能满足项目的 演进防线,需要需找一种解耦的方式替代当前的开发模式。
痛点四:不满足业务需求
随着公司业务的不断发展,仅仅只有浏览器端的 web 应用已经逐渐显得有些不够用了,目前又是移动互联网急剧增长的时代,手机端的原生 App 应用已经非常成熟,随着 App 软件的大量普及越来越多的企业也加入到 App 软件开发当中来,为了尽可能的抢占商机和提升用户体验,你所在的公司可能也不会把所有的开发资源都放在 web 应用上,而是多端应用同时开发,此时公司的业务线可能就是如下的几种或者其中一部分:
浏览器端的 web 应用、iOS 原生 App、安卓端原生 App、微信小程序等等,可能只是开发其中的一部分产品,但是除了 web 应用能够使用传统的 MVC 模式开发外,其他的都无法使用该模式进行开发,像原生 App 或者微信小程序都是通过调用 RESTful api 的方式与后端进行数据交互。
这也就是我们今天所说的第四个痛点:无法满足业务需求,有些同学可能会认为前端开发人员只有网页开发人员,所以在心底里就会觉得 MVC 开发模式并没有那么不堪,当然,我也觉得 MVC 开发模式非常优秀,但是它也有它的一些不足,当业务线扩大时,仅仅只有 MVC 一种开发模式显然是无法让人满意的。
以上这四个痛点急需解决,这也是我们为什么需要前后端分离的几点原因。
什么是前后端分离
下面重点讲解下什么是前后端分离,概念相对比较多,大家请耐心仔细阅读。
前后端分离是一种项目开发模式
当业务变得越来越复杂或者产品线越来越多,原有的开发模式已经无法满足业务需求,当端上的产品越来越多,展现层的变化越来越快、越来越多,此时就应该进行前后端分离分层抽象,简化数据获取过程,比如目前比较常用的就是前端人员自行实现跳转逻辑和页面交互,后端只负责提供接口数据,二者之间通过调用 RESTful api 的方式来进行数据交互,如下图所示:
此时就不会出现 html 代码需要转成 JSP 进行开发的情况,前端项目只负责前端部分,并不会掺杂后端代码,这样的话代码不再耦合。同时,前端项目与后端项目也不会再出现耦合严重的现象,只要前后端协商和定义好接口规范及数据交互规范,双方就可以并行开发,互不干扰,业务也不会耦合,两端只通过接口来进行交互。
在 MVC 模式开发项目时,往往后端过重,“控制权”也比较大,既要负责处理业务逻辑、权限管理等后端操作,也需要处理页面跳转等逻辑,在前后端分离的模式中,后端由原来的大包大揽似的独裁者变成了接口提供者,而前端也不仅仅是原来那样仅处理小部分业务,页面跳转也不再由后端来处理和决定,整个项目的控制权已经由后端过渡至前端来掌控,前端需要处理的更多。
前端项目和后端项目隔离开来、互不干涉,通过接口和数据规范来完成项目功能需求,这也是目前比较流行的一种开发方式。
前后端分离是一种人员分工模式
为什么说前后端分离是一种人员分工模式?前后端分离的核心就是后台负责数据提供,前端负责显示交互,在这种开发模式下,前端开发人员和后端开发人员分工明确,职责划分十分清晰,双方各司其职,不会存在边界不清晰的地方。
前端开发人员包括 web 开发人员、原生 App 开发人员,后端开发则是指 Java 开发人员(以 Java 语言为例),不同的开发人员只需要注重自己所负责的项目即可。后端专注于控制层(RESTful API)、服务层 、数据访问层,前端专注于前端控制层、 视图层,不会再出现前端人员需要维护部分后端代码,或者后端开发人员需要去调试样式等等职责不清和前后端耦合的情况,我们通过两张项目开发流程简图来对比:
此时的开发过程中会存在前后端耦合的情况,如果出现问题前端需要返工、后端也需要返工,开发效率会有所影响,前后端分离后,流程简图如下:
前后端分离后,与原有的开发模式有了较大的不同,此时就可以开发多端产品,在设计完成后,web 端开发人员、App 端开发人员、后端开发人员都可以投入到开发工作当中,能够做到并行开发,前端开发人员与后端开发人员职责分离,即使出现问题,也是修复各自的问题不会互相影响和耦合,开发效率高且满足企业对于多产品线的开发需求。
前后端分离是一种项目部署模式(架构模式)
前后端分离后,各端应用可以独立打包部署,并针对性的对部署方式进行优化,不再是前后端一个统一的工程最终打成一个部署包进行部署。以 web 应用为例,前端项目部署后,不再依赖于 Servlet 容器,可以使用吞吐量更大的 Nginx 服务器,采用动静分离的部署方式,既提升了前端的访问体验,也减轻了后端服务器的压力,再进一步优化的话,可以使用页面缓存、浏览器缓存等设置,也可以使用 CDN 等产品提升静态资源的访问效率。对于后端服务而言,可以进行集群部署提升服务的响应效率,也可以进一步的进行服务化的拆分等等。前后端分离后的独立部署维护以及针对性的优化,可以加快整体响应速度和吞吐量。
前后端分离的优点和注意事项
优点补充
关于它的优点其实在前文中已经提到了很多,这里再简单的进行一些补充:
1、可以真正实现前后端的解耦,不仅仅是开发方式的改进,前后端开发人员的职责也更加清晰,对于整个技术团队有很大的益处。
2、并行开发可以有效的提升开发效率,因为可以前后端并行开发,而不再是前后端代码强依赖。
3、职责分明意味着出现问题可以快速的责任到人,不会出现互相推诿的现象。
4、前后端开发的解耦也会增加各端代码的维护性和易读性。
5、尽早的使用前后端分离的开发模式,一旦业务扩张需要进行多产品开发,如 App 、微信小程序等,后端接口只需要些许的增改即可,因为有大量的复用接口,大大提升效率。
6、前端项目部署时不需要重启服务器,无缝升级。
7、分开部署也会进一步减轻后端服务器的压力。
注意事项
1、前端开发资源是否充足
由于所在公司以往项目采用传统开发风格,即以后端 MVC 为主的开发模式,前端人员仅仅提供静态 html 页面即可,但是采用前后端分离的开发模式,我们在前文中也已经提到了这种开发模式会将后端的控制权弱化并增强前端的控制权,也就是后端开发人员的压力会减少,同时前端开发人员负责的东西更多了,不再是简单的交互效果和静态页面,路由规则、跳转逻辑、数据交互和页面渲染都需要考虑进来,现在前端技术又是百花齐放,组件化、模块化等等都使得对于前端开发人员的要求变高,所以在进行开发模式更改前一定要量力而行,在没有足够知识和人才储备的情况下不要贸然开展重构工作。
2、软件迭代周期需要慎重估算
对于中小型团队来说,一般需要一个比较快的软件迭代周期,而此时不仅仅是前端人员配备不足,甚至后端人员也不是十分充足,这种情况下采用前后端分离模式,增加了一个接口制定流程和前后端联调流程,可能会放慢迭代周期,如果是项目转型的话,甚至需要多次重构,因此不能盲目进行。
3、并不是所有的项目开发都需要这种模式
如果项目比较简单或者一个项目需要快速开发上线的话,可以采用普遍使用的 MVC 开发模式快速迭代,此时需要考虑的是实用性和迭代速度,在不熟悉前后端分离模式的情况下不要贸然做出定论。
4、前后端开发人员的沟通成本
前后端分离后,无论是 API 接口的对接还是测试工作,都涉及到前后端人员的沟通,很多公司采用前后端分离后,前后端协作模式配合力度底,互相等待,开发效率低下,反而不如传统的开发模式。
以上简单的整理了一些注意事项,如果有补充的话欢迎与我交流。
实验总结
由于我们最终的实践项目是一个前后端分离的项目,因此选择在这一篇文章向大家介绍前后端分离这一概念,与传统的 MVC 开发模式相比,前后端分离模式有更多的优点,在我的理解中,它既是一种项目开发模式,也是一种人员分工模式,同时也是一种项目部署模式,能够使得前后端开发工作不再强耦合,提升开发人员的整体效率,但是我们在最后也提醒大家,并不是所有项目或者所有团队都适合这种模式,因为它对于前后端开发人员都有一定的要求,如果在不熟悉它的情况下贸然使用,反而有可能拖慢整体的开发进度,因此一定要慎重考虑,在足够有把握的情况下再去进行项目的重构和优化。