共享资源组前后端分离演化过程

Posted 京东虚拟平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了共享资源组前后端分离演化过程相关的知识,希望对你有一定的参考价值。

前后端分离已经成为现在互联网Web开发的趋势和普遍现象。从网上可以找到某些互联网公司在2014年前后分享出来的课件。而公司内部wiki上也能看到,最近一两年前后端分离的实践者是越来越多。从2016年底,共享资源组也开始实现前后端分离。


本篇首先阐述前后端分离模式的特征和原因,其次会介绍共享资源组前端架构的演变过程。


1. 什么是前后端分离


顾名思义,前后端分离,就是前端和后端分开。可是这种说法比较笼统,并没有阐述清晰分离的界限和分离的方式。比如有人会说,我们现在一个Web项目,首先有前端工程师完成页面和交互的模版,然后再有Java工程师嵌入数据引用与处理的Java模版代码,不也是前后端分离吗?非也非也,这充其量算是后端Java的MVC模式。还有一部人会认为,我们现在前端获取数据都是Ajax异步请求的方式获取数据,不就是前后端分离了呢?非也非也,前后端分离,不仅要看开发时数据获取的方式,还要看最终前端代码部署在哪里,如果html和Js文件都和Java API部署在同一Tomcat下,那么仍然不能算是严格的前后端分离。


从概念上来讲,前后端分离本身就不存在一个明确的定义。本篇中的前后端分离讲的是严格的前后端分离,前端开发过程和部署是完全独立的,前端对后端的依赖仅仅限于契约(API文档)服务(API服务)


2. 为什么要分离?


关于前后端分离的原因,归纳如下:

  • 职责的细分。过去开发Web应用,通常都需要后端工程师懂得部分前端开发技术,如JS、Html、CSS等。而后端工程师,往往不太喜欢做前端的工作,并且会影响其处理数据的专注,所以就迫切需要将前端页面相关功能给独立出来,交由前端工程师独立负责。

  • 技术的进步。最近五六年,前端的技术发展极其迅速,也较过去先进太多,尤其是Node.js的出现,不论是从开发方式还是部署方式到要方便很多,最终的能够的为前端从服务端独立出来奠定了技术基础。

  • 开发效率的迫切要求。这点不多说了,任何一家不注重效率的私人公司,早晚会进入泥潭。

  • 产品对匠人的需求。目前互联网产品要求的质量要远高于几年之前,要想达到极致的体验,如同精美工艺品需要某领域匠人的精心打磨一样,产品对技术深度的要求越来越高,如果还是过去那种前后端揉合开发,那么最终是前端和后端工程师很难在擅长领域达到匠人的高度。


3. 如何分离?


分离的过程没有一个统一的标准,关于分离的目标,从网上可以找到一些答案,比如阿里的中途岛项目的架构就是一个值得参考的例子(图1)。


(图1)


限于公司环境的限制,资源的限制,部门很难一步就达到前后端彻底分离的效果。以下就针对部门的情况,介绍下共享资源组前后端分离架构的演化过程以及下一步优化。


3.1 团队成立之前


共享资源组前后端分离演化过程

(图2)


在团队成立之前,部门所有的项目都不是前后端分离,而是传统的后端MVC模式。


MVC模式中,虽然从功能上View层和Model、Controller是分离的,但是View层的模版技术通常是后端模版引擎技术(JSP、Velocity、FreeMaker、Thymeleaf),对于前端工程师而言,尤其不便。并且部署还是个棘手的问题,前端一点小的改动就需要后端Java服务重新部署。在MVC模式下,同样也是可以使用Ajax,这也是为什么说使用Ajax并不代表是前后端分离,Ajax技术是前后端分离的必要非充分条件。


如果仍有项目必须采用MVC模式开发,建议采用Thymeleaf,Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎,最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用,但是运行时仍然要部署到Java Web容器内。


3.2 独立出前端应用(网关)


共享资源组前后端分离演化过程

(图3)


团队成立后,一方面为了提高前端开发的效率,另外一方面避免后端去翻译模版文件及嵌入逻辑代码,有必要将原有的MVC模式的Web应用中View层和Controller层拆分出来,而后端只提供JSF服务。因此独立出来一个前端应用(目前多数人理解为网关)


此次独立出前端应用中,完成以下工作:

  • 前端开发工程师采用Ajax获取页面数据,然后利用前端的模版引擎(Vue框架提供),渲染为最终展示页面;

  • 前端应用完成用户认证、聚合JSF服务、并将JSF服务转换为Http RESTFul服务,供前端调用;


从部署角度而言,前端应用(包括HTML)和静态资源(JS)是分开的,之所以HTML文件部署到前端应用中,主要是避免跨域的问题。静态资源却是多个项目一块儿部署,一方面是为部门节省资源服务器,另一方面公司部署环境对静态资源的支持有限,要比部署Java项目麻烦的多。


3.3 拆分前端应用


共享资源组前后端分离演化过程

(图4)


目前团队的项目除了开发M端,还同时会开发PC端。PC端和M端的代码是复用的,但是部署却是要区别开的。拆分前端应用为纯前端应用(nginx)和应用网关两部分,同时将PC端和M端的API部分合并为一个服务,而成为真正的应用网关。目前纯前端应用主要是合并HTML和静态资源(JS),如此处理,才真正的将前后端彻底的分离。(之前HTML文件和API部署在一起,并非与JS一块儿部署)


到目前为止,前端才真正地完全控制了所有前端的部署。前后端的交互只剩下了契约和服务。


3.4 进一步优化


(图5)


前端的技术的发展虽然迅速,可是J-one、Jdos对Node.js应用发布的长时间不支持,导致纯前端应用只能以静态资源的方式发布。这也局限了前端新技术的应用。好消息是J-one开始对Node.js支持,虽然还不如对Java的支持力度,但是理论上可以成功落的。


主要解决如下问题:

  • SEO的支持。之前前后端分离后,因为无法部署Node.js环境,所以只能采用单页应用,完全在前端渲染页面,能部署Node.js服务后,有SEO需求的页面,就可以采用服务端渲染;

  • 像部署Java项目一样在J-one上部署前端应用。


优化后的架构其实和阿里的中途岛项目非常相似,区别主要在于后端服务的处理。中途岛项目的Node.js,会直接调用SOAP服务(类似JSF),直接组合服务。而我们的架构中,在JSF服务和Node.js服务之间还有一层薄的应用层,负责处理用户认证、聚合JSF服务、并将JSF服务转换为Http RESTFul服务。


4. 契约


契约(API文档)是提高前端开发效率以及减少前后端工作交互的必要条件。开发阶段,契约一旦确定,前后端完全可以独立并行开发。所以契约的制定和遵守就显得格外重要。


契约的制定,目前比较好的方案是依据RESTFul模式来定义接口,RESTFul接口是无状态的,被称为轻量的SOP,天然支持分布式,易于横向扩展。RESTFul接口的简洁,大大降低了开发一个Web服务的复杂度。


图6


契约的展现形式很多,有些团队是在doc文档中描述接口,有些团队是在md文档描述接口,但是这种纯文档的方式的方式的维护成本较高。目前比较流行的是提供Swaager文档。Swagger是接口定义的一个规范,在Java项目集成Swagger插件后,可以自动生成文档内容,如此就不再需要开发者将更改内容同步到文档内,也降低了维护成本。


5. 总结


前后端分离将前端和后端的职责明确划分,彼此更专注于擅长的领域。之间的交互主要依赖于API文档(开发阶段)和API服务(运行阶段)。如同诚信在人类社会的重要性一样,API文档的可靠性、规范性会严重影响到前后端分离后开发的效率。


目前团队的前后端分离架构还在演化过程,离最终的目标还有一定距离,尤其是前端的部署还远没有达到后端的持续部署程度,这不仅需要公司相关兄弟部门的后续优化和大力支持,更需要团队人员勇于探索新技术的精神。

以上是关于共享资源组前后端分离演化过程的主要内容,如果未能解决你的问题,请参考以下文章

前端大讲堂基于Vue的前后端分离实践

论前后端分离的好处

论前后端分离的好处

前后端分离的开源人力资源系统

干货基于Vue的前后端分离实践

前后端分离及React的一些研究