关于前后端分离:前后端分离架构Web-实现前后端分离前后端解耦

3次阅读

共计 8919 个字符,预计需要花费 23 分钟才能阅读完成。

前后端拆散曾经成为了行业的支流,大流量时代,微服务的呈现,让前后端拆散倒退更是迅速,前端框架 vue.js、angura.js 的迅速倒退,也让前后端拆散趋势放慢。

我的公众号:MarkerHub,Java 网站:https://markerhub.com

更多精选文章请点击:Java 笔记大全.md


作者 | 山河远阔

起源 | www.blog.csdn.net/weixin_37539378

一、前言

”前后端拆散“曾经成为互联网我的项目开发的业界标杆,通过 Tomcat+Ngnix(也能够两头有个 Node.js),无效地进行解耦。并且前后端拆散会为当前的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户端,例如:浏览器,车载终端,安卓,IOS 等等)打下松软的根底。

前后端拆散 (解耦) 的核心思想是:前端 Html 页面通过 Ajax 调用后端的 RestFul API 并应用 Json 数据进行交互。

注:【在互联网架构中,web 服务器:个别指像 nginx,apache 这类的服务器,他们个别只能解析动态资源。应用服务器:个别指像 tomcat,jetty,resin 这类的服务器能够解析动静资源也能够解析动态资源,但解析动态资源的能力没有 web 服务器好。】

个别只有 Web 服务器能力被外网拜访,应用服务器只能内网拜访。

二、为什么前后端拆散

个别公司后端开发人员间接兼顾前端的工作,一边实现 API 接口,一边开发页面,两者相互切换着做,而且依据不同的 url 动静拼接页面,这也导致后盾的开发压力大大增加。前后端工作调配不均。不仅仅开发效率慢,而且代码难以保护。

而前后端拆散的话,则能够很好的解决前后端分工不均的问题,将更多的交互逻辑调配给前端来解决,而后端则能够专一于其本职工作,比方提供 API 接口,进行权限管制以及进行运算工作。而前端开发人员则能够利用 nodejs 来搭建本人的本地服务器,间接在本地开发,而后通过一些插件来将 api 申请转发到后盾,这样就能够齐全模仿线上的场景,并且与后盾解耦。前端能够独立实现与用户交互的整一个过程,两者都能够同时动工,不相互依赖,开发效率更快,而且分工比拟平衡。

三、从 MVC 到前后端拆散

MVC 是一种经典的设计模式,全名为 Model-View-Controller,即 模型 – 视图 – 控制器。

其中,模型 是用于封装数据的载体,例如,在 Java 中个别通过一个简略的 POJO(Plain Ordinary Java Object)来示意,其本质是一个一般的 Java Bean,蕴含一系列的成员变量及其 getter/setter 办法。对于 视图 而言,它更加偏重于展示,也就是说,视图决定了界面到底长什么样子,在 Java 中可通过 JSP 来充当视图,或者通过纯 HTML 的形式进行展示,而后者才是目前的支流。模型和视图须要通过 控制器 来进行粘合,例如,用户发送一个 HTTP 申请,此时该申请首先会进入控制器,而后控制器去获取数据并将其封装为模型,最初将模型传递到视图中进行展示。

综上所述,MVC 的交互过程如下图所示:

也就是说,咱们输出的是 AJAX 申请,输入的是 JSON 数据,市面上有这样的技术来实现这个性能吗?答案是 REST。

REST 全称是 Representational State Transfer(表述性状态转移),它是 Roy Fielding 博士在 2000 年写的一篇对于软件架构格调的论文,此文一出,威震四方!国内外许多出名互联网公司纷纷开始采纳这种轻量级的 Web 服务,大家习惯将其称为 RESTful Web Services,或简称 REST 服务。

如果将浏览器这一端视为前端,而服务器那一端视为后端的话,能够将以上改良后的 MVC 模式简化为以下前后端拆散模式:

可见,有了 REST 服务,前端关注界面展示,后端关注业务逻辑,分工明确,职责清晰。

四、意识 Rest 架构

REST 实质上是应用 URL 来拜访资源种形式。家喻户晓,URL 就是咱们平时应用的申请地址了,其中包含两局部:申请形式 与 申请门路,比拟常见的申请形式是 GET 与 POST,但在 REST 中又提出了几种其它类型的申请形式,汇总起来有六种:GET、POST、PUT、DELETE、HEAD、OPTIONS。

尤其是前四种,正好与 CRUD(Create-Retrieve-Update-Delete,增删改查)四种操作绝对应,例如,GET(查)、POST(增)、PUT(改)、DELETE(删),这正是 REST 与 CRUD 的殊途同归之妙!须要强调的是,REST 是“面向资源”的,这里提到的资源,实际上就是咱们常说的畛域对象,在零碎设计过程中,咱们常常通过畛域对象来进行数据建模。

REST 是一个“无状态”的架构模式,因为在任何时候都能够由客户端发出请求到服务端,最终返回本人想要的数据,以后申请不会受到上次申请的影响。也就是说,服务端将外部资源公布 REST 服务,客户端通过 URL 来拜访这些资源,这不就是 SOA 所提倡的“面向服务”的思维吗?所以,REST 也被人们看做是一种“轻量级”的 SOA 实现技术,因而在企业级利用与互联网利用中都失去了广泛应用。

上面咱们举几个例子对 REST 申请进行简略形容:

可见,申请门路雷同,但申请形式不同,所代表的业务操作也不同,例如,/advertiser/1 这个申请,带有 GET、PUT、DELETE 三种不同的申请形式,对应三种不同的业务操作。

尽管 REST 看起来还是很简略的,实际上咱们往往须要提供一个 REST 框架,让其实现前后端拆散架构,让开发人员将精力集中在业务上,而并非那些具体的技术细节。

五、前后端拆散意义大吗?

1、该网站前端变动远比后端变动频繁,则意义大。

2、该网站尚处于原始开发模式,数据逻辑与体现逻辑混淆不清,则意义大。

3、该网站前端团队和后端团队分属两个领导班子,技能点差别很大,则意义大。

4、该网站前端成果壮丽 / 跨设施兼容要求高,则意义大。

六、术业有专攻(开发人员拆散)

以前的 JavaWeb 我的项目大多数都是 java 程序员又当爹又当妈,又搞前端(ajax/jquery/js/html/css 等等),又搞后端(java/mysql/oracle 等等)。

随着时代的倒退,慢慢的许多大中小公司开始把前后端的界线分的越来越明确,前端工程师只管前端的事件,后端工程师只管后端的事件。

正所谓术业有专攻,一个人如果什么都会,那么他毕竟什么都不精。

大中型公司须要专业人才,小公司须要全才,然而对于集体职业倒退来说,我倡议是离开。

对于后端 java 工程师:

把精力放在 java 根底,设计模式,jvm 原理,spring+springmvc 原理及源码,linux,mysql 事务隔离与锁机制,mongodb,http/tcp,多线程,分布式架构(dubbo,dubbox,spring cloud),弹性计算架构,微服务架构(springboot+zookeeper+docker+jenkins),java 性能优化,以及相干的项目管理等等。

后端谋求的是:三高(高并发,高可用,高性能),平安,存储,业务等等。

对于前端工程师:

把精力放在 html5,css3,jquery,angularjs,bootstrap,reactjs,vuejs,webpack,less/sass,gulp,nodejs,Google V8 引擎,javascript 多线程,模块化,面向切面编程,设计模式,浏览器兼容性,性能优化等等。

前端谋求的是:页面体现,速度晦涩,兼容性,用户体验等等。

tips:大家能够关注微信公众号:Java 后端,获取更多优良博文推送。

七、耦合时代

几曾何时,咱们的 JavaWeb 我的项目都是应用了若干后盾框架,springmvc/struts + spring + spring jdbc/hibernate/mybatis 等等。

大多数我的项目在 java 后端都是分了三层,管制层(controller/action),业务层(service/manage),长久层(dao)。

管制层负责接管参数,调用相干业务层,封装数据,以及路由 & 渲染到 jsp 页面。

而后 jsp 页面上应用各种标签(jstl/el/struts 标签等)或者手写 java 表达式(<%=%>)将后盾的数据展示进去,玩的是 MVC 那套思路。

咱们先看这种状况:需要定完了,代码写完了,测试测完了,而后呢?要公布了吧?

你须要用 maven 或者 eclipse 等工具把你的代码打成一个 war 包,而后把这个 war 包公布到你的生产环境下的 web 容器(tomcat/jboss/weblogic/websphere/jetty/resin)里,对吧?

公布完了之后,你要启动你的 web 容器,开始提供服务,这时候你通过配置域名,dns 等等相干,你的网站就能够拜访了(假如你是个网站)。

那咱们来看,你的前后端代码是不是全都在那个 war 包里?包含你的 js,css,图片,各种第三方的库,对吧?

好,上面在浏览器中输出你的网站域名(www.xxx.com),之后产生了什么?(这个问题也是很多公司的面试题)

我捡干的说了啊,根底不好的童鞋请本人去搜。

浏览器在通过域名通过 dns 服务器找到你的服务器外网 ip, 将 http 申请发送到你的服务器,在 tcp3 次握手之后(http 上面是 tcp/ip),通过 tcp 协定开始传输数据,你的服务器失去申请后,开始提供服务,接管参数,之后返回你的应答给浏览器,浏览器再通过 content-type 来解析你返回的内容,出现给用户。

那么咱们来看,咱们先假如你的首页中有 100 张图片,此时,用户的看似一次 http 申请,其实并不是一次,用户在第一次拜访的时候,浏览器中不会有缓存,你的 100 张图片,浏览器要连着申请 100 次 http 申请(有人会跟我说 http 长连短连的问题,不在这里探讨),你的服务器接管这些申请,都须要消耗内存去创立 socket 来玩 tcp 传输(耗费你服务器上的计算资源)。

重点来了,这样的话,你的服务器的压力会十分大,因为页面中的所有申请都是只申请到你这台服务器上,如果 1 集体还好,如果 10000 集体并发拜访呢(先不聊服务器集群,这里就说是单实例服务器),那你的服务器能扛住多少个 tcp 连贯?你的带宽有多大?你的服务器的内存有多大?你的硬盘是高性能的吗?你能抗住多少 IO?你给 web 服务器分的内存有多大?会不会宕机?

这就是为什么,越是大中型的 web 利用,他们越是要解耦。

实践上你能够把你的数据库 + 应用服务 + 音讯队列 + 缓存 + 用户上传的文件 + 日志 + 等等都扔在一台服务器上,你也不必玩什么服务治理,也不必做什么性能监控,什么报警机制等等,就乱成一锅粥好了。

然而这样就如同是你把鸡蛋都放在一个篮子里,隐患十分大。如果因为一个子利用的内存不稳固导致整个服务器内存溢出而 hung 住,那你的整个网站就挂掉了。

如果出意外挂掉,而恰好这时你们的业务又处于井喷式倒退高峰期,那么祝贺你,业务胜利被技术卡住,很可能会散失大量用户,结果不堪设想。
留神:技术肯定是要走在业务后面的,否则你将错过最佳的发展期。

此外,你的利用全副都耦合在一起,相当于一个巨石,当服务端负载能力有余时,个别会应用负载平衡的形式,将服务器做成集群,这样其实你是在程度扩大一块块巨石,性能加速度会越来越低,要晓得,自身负载就低的性能 or 模块是没有必要程度扩大的,在本文中的例子就是你的性能瓶颈不在前端,那干嘛要程度扩大前端呢???
还有发版部署上线的时候,我明明只改了后端的代码,为什么要前端也跟着公布呢???(援用:《架构探险 – 轻量级微服务架构》,黄勇)

失常的互联网架构,是都要拆开的,你的 web 服务器集群,你的应用服务器集群 + 文件服务器集群 + 数据库服务器集群 + 音讯队列集群 + 缓存集群等等。

JSP 的痛点

以前的 javaWeb 我的项目大多数应用 jsp 作为页面层展现数据给用户,因为流量不高,因而也没有那么刻薄的性能要求,但当初是大数据时代,对于互联网我的项目的性能要求是越来越高,因而原始的前后端耦合在一起的架构模式曾经逐步不能满足咱们,因而咱们须要需找一种解耦的形式,来大幅度晋升咱们的负载能力。

1、动静资源和动态资源全副耦合在一起,服务器压力大,因为服务器会收到各种 http 申请,例如 css 的 http 申请,js 的,图片的等等。

一旦服务器呈现情况,前后台一起玩完,用户体验极差。

2、UI 出好设计图后,前端工程师只负责将设计图切成 html,须要由 java 工程师来将 html 套成 jsp 页面,出错率较高(因为页面中常常会呈现大量的 js 代码),
批改问题时须要单方协同开发,效率低下。

3、jsp 必须要在反对 java 的 web 服务器里运行(例如 tomcat,jetty,resin 等),无奈应用 nginx 等(nginx 据说单实例 http 并发高达 5w,这个劣势要用上),
性能提不上来。

4、第一次申请 jsp,必须要在 web 服务器中编译成 servlet,第一次运行会较慢。

  1. 每次申请 jsp 都是拜访 servlet 再用输入流输入的 html 页面,效率没有间接应用 html 高(是每次哟,亲~)。

6、jsp 内有较多标签和表达式,前端工程师在批改页面时会顾此失彼,遇到很多痛点。

7、如果 jsp 中的内容很多,页面响应会很慢,因为是同步加载。

8、须要前端工程师应用 java 的 ide(例如 eclipse),以及须要配置各种后端的开发环境,你们有思考过前端工程师的感触吗。

基于上述的一些痛点,咱们应该把整个我的项目的开发权重往前移,实现前后端真正的解耦!

开发模式

以前老的形式是:

  • 产品经验 / 领导 / 客户提出需要
  • UI 做出设计图
  • 前端工程师做 html 页面
  • 后端工程师将 html 页面套成 jsp 页面(前后端强依赖,后端必须要等前端的 html 做好能力套 jsp。如果 html 产生变更,就更痛了,开发效率低)
  • 集成呈现问题
  • 前端返工
  • 后端返工

二次集成

集成胜利

交付

新的形式是:

  • 产品经验 / 领导 / 客户提出需要
  • UI 做出设计图
  • 前后端约定接口 & 数据 & 参数
  • 前后端并行开发(无强依赖,可前后端并行开发,如果需要变更,只有接口 & 参数不变,就不必两边都批改代码,开发效率高)
  • 前后端集成
  • 前端页面调整
  • 集成胜利
  • 交付

申请形式

以前老的形式是:

  • 客户端申请
  • 服务端的 servlet 或 controller 接管申请(后端管制路由与渲染页面,整个我的项目开发的权重大部分在后端)
  • 调用 service,dao 代码实现业务逻辑
  • 返回 jsp
  • jsp 展示一些动静的代码

新的形式是:

  • 浏览器发送申请
  • 间接达到 html 页面(前端管制路由与渲染页面,整个我的项目开发的权重前移)
  • html 页面负责调用服务端接口产生数据(通过 ajax 等等,后盾返回 json 格局数据,json 数据格式因为简洁高效而取代 xml)
  • 填充 html,展示动态效果,在页面上进行解析并操作 DOM。

(有趣味的童鞋能够拜访一下阿里巴巴等大型网站,而后按一下 F12,监控一下你刷新一次页面,他的 http 是怎么玩的,大多数都是独自申请后盾数据,应用 json 传输数据,而不是一个大而全的 http 申请把整个页面包含动 + 静全副返回过去)

总结一下新的形式的申请步骤:

大量并发浏览器申请 —>web 服务器集群 (nginx)—> 应用服务器集群 (tomcat)—> 文件 / 数据库 / 缓存 / 音讯队列服务器集群

同时又能够玩分模块,还能够按业务拆成一个个的小集群,为前面的架构降级做筹备。

前后拆散的劣势

1、能够实现真正的前后端解耦,前端服务器应用 nginx。

前端 / WEB 服务器放的是 css,js,图片等等一系列动态资源(甚至你还能够 css,js,图片等资源放到特定的文件服务器,例如阿里云的 oss,并应用 cdn 减速),前端服务器负责管制页面援用 & 跳转 & 路由,前端页面异步调用后端的接口,后端 / 应用服务器应用 tomcat(把 tomcat 设想成一个数据提供者),放慢整体响应速度。

这里须要应用一些前端工程化的框架比方 nodejs,react,router,react,redux,webpack

2、发现 bug,能够疾速定位是谁的问题,不会呈现相互踢皮球的景象。

页面逻辑,跳转谬误,浏览器兼容性问题,脚本谬误,页面款式等问题,全副由前端工程师来负责。

接口数据出错,数据没有提交胜利,应答超时等问题,全副由后端工程师来解决。

单方互不烦扰,前端与后端是相亲相爱的一家人。

3、在大并发状况下,我能够同时程度扩大前后端服务器,比方淘宝的一个首页就须要 2000 + 台前端服务器做集群来抗住日均多少亿 + 的日均 pv。

去加入阿里的技术峰会,听他们说他们的 web 容器都是本人写的,就算他单实例抗 10 万 http 并发,2000 台是 2 亿 http 并发,并且他们还能够依据预知洪峰来有限拓展,很恐怖,就一个首页。。。

4、缩小后端服务器的并发 / 负载压力

除了接口以外的其余所有 http 申请全副转移到前端 nginx 上,接口的申请调用 tomcat,参考 nginx 反向代理 tomcat。

且除了第一次页面申请外,浏览器会大量调用本地缓存。

5、即便后端服务临时超时或者宕机了,前端页面也会失常拜访,只不过数据刷不进去而已。

6、兴许你也须要有微信相干的轻利用,那样你的接口齐全能够共用,如果也有 app 相干的服务,那么只有通过一些代码重构,也能够大量复用接口,晋升效率。(多端利用)

7、页面显示的货色再多也不怕,因为是异步加载。

8、nginx 反对页面热部署,不必重启服务器,前端降级更无缝。

9、减少代码的维护性 & 易读性(前后端耦在一起的代码读起来相当吃力)。

10、晋升开发效率,因为能够前后端并行开发,而不是像以前的强依赖。

11、在 nginx 中部署证书,外网应用 https 拜访,并且只凋谢 443 和 80 端口,其余端口一律敞开(避免黑客端口扫描),
内网应用 http,性能和平安都有保障。

12、前端大量的组件代码得以复用,组件化,晋升开发效率,抽出来!

注意事项

1、在开需要会议的时候,前后端工程师必须全副加入,并且须要制订好接口文档,后端工程师要写好测试用例(2 个维度),不要让前端工程师充当你的专职测试,
举荐应用 chrome 的插件 postman 或 soapui 或 jmeter,service 层的测试用例拿 junit 写。ps:前端也能够玩单元测试吗?

2、上述的接口并不是 java 里的 interface,说白了调用接口就是调用你 controler 里的办法。

3、减轻了前端团队的工作量,加重了后端团队的工作量,进步了性能和可扩展性。

4、咱们须要一些前端的框架来解决相似于页面嵌套,分页,页面跳转管制等性能。(下面提到的那些前端框架)。

5、如果你的我的项目很小,或者是一个单纯的内网我的项目,那你大可释怀,不必任何架构而言,然而如果你的我的项目是外网我的项目,呵呵哒。

6、以前还有人在应用相似于 velocity/freemarker 等模板框架来生成动态页面,仁者见仁智者见智。

7、这篇文章次要的目标是说 jsp 在大型外网 java web 我的项目中被淘汰掉,可没说 jsp 能够齐全不学,对于一些学生敌人来说,jsp/servlet 等相干的 java web 根底还是要把握牢的,不然你认为 springmvc 这种框架是基于什么来写的?

8、如果页面上有一些权限等等相干的校验,那么这些相干的数据也能够通过 ajax 从接口里拿。

9、对于既能够前端做也能够后端做的逻辑,我倡议是放到前端,为什么?

因为你的逻辑须要计算资源进行计算,如果放到后端去 run 逻辑,则会耗费带宽 & 内存 & cpu 等等计算资源,你要记住一点就是:服务端的计算资源是无限的,而如果放到前端,应用的是客户端的计算资源,这样你的服务端负载就会降落(高并发场景)。

相似于数据校验这种,前后端都须要做!

10、前端须要有机制应答后端申请超时以及后端服务宕机的状况,敌对的展现给用户。

扩大浏览

1、其实对于 js,css,图片这类的动态资源能够思考放到相似于阿里云的 oss 这类文件服务器上(如果是一般的服务器 & 操作系统,存储在达到 pb 级的文件后,或者单个文件夹内的文件数量达到 3-5 万,io 会有很重大的性能问题),再在 oss 上配 cdn(全国子节点减速),这样你页面关上的速度像飞一样,无论你在全国的哪个中央,并且你的 nginx 的负载会进一步升高。

2、如果你要玩轻量级微服务架构,要应用 nodejs 做网关,用 nodejs 的益处还有利于 seo 优化,因为 nginx 只是向浏览器返回页面动态资源,而国内的搜索引擎爬虫只会抓取静态数据,不会解析页面中的 js,这使得利用得不到良好的搜索引擎反对。同时因为 nginx 不会进行页面的组装渲染,须要把动态页面返回到浏览器,而后实现渲染工作,这减轻了浏览器的渲染累赘。

浏览器发动的申请通过 nginx 进行散发,URL 申请对立散发到 nodejs,在 nodejs 中进行页面组装渲染;API 申请则间接发送到后端服务器,实现响应。

3、如果遇到跨域问题,spring4 的 CORS 能够完满解决,但个别应用 nginx 反向代理都不会有跨域问题,除非你把前端服务和后端服务分成两个域名。
JSONP 的形式也被淘汰掉了。

4、如果想玩多端利用,留神要去掉 tomcat 原生的 session 机制,要应用 token 机制,应用缓存(因为是分布式系统),做单点,对于 token 机制的安全性问题,能够搜一下 jwt。

5、前端我的项目中能够退出 mock 测试(结构虚构测试对象来模仿后端,能够独立开发和测试),后端须要有具体的测试用例,保障服务的可用性与稳定性。

总结

前后端拆散并非仅仅只是一种开发模式,而是一种架构模式(前后端拆散架构)。

千万不要认为只有在撸代码的时候把前端和后端离开就是前后端拆散了。须要辨别前后端我的项目。前端我的项目与后端我的项目是两个我的项目,放在两个不同的服务器,须要独立部署,两个不同的工程,两个不同的代码库,不同的开发人员。

前后端工程师须要约定交互接口,实现并行开发,开发完结后须要进行独立部署,前端通过 ajax 来调用 http 申请调用后端的 restful api。

前端只须要关注页面的款式与动态数据的解析 & 渲染,而后端专一于具体业务逻辑。

正文完
 0