[透彻]为什么要前后端分离?

2023-11-19

前后端分离的意义

前后端分离,已成为互联网项目开发的业界标准使用方式

前后端分离,会为以后的大型分布式架构、弹性计算架构、微服务架构打下坚实的基础。

核心思想: 前端页面调用后端的restuful api接口,并使用json数据进行交互。

服务器种类

  • web服务器

例如 nginx,apache这类服务器,一般只能解析静态资源

  • 应用服务器

例如 tomcat,jetty,resin这类服务器,可以解析动态资源,也可以解析静态资源,但解析静态资源的速度没有web服务器高效

一般而言,只有web服务器才能被外网访问,而应用服务器只能通过内网访问

以前的开发模式

早期的JavaWeb项目并不复杂,业务场景和逻辑都很简单,开发比较便捷。

因此,大多数都是java程序员又当爹又当妈,既搞前端(html/css/javascript/jsp),又搞后端(java/MySQL/ORM框架/接口开发)。

随着时代发展,很多公司的规模越来越大,业务场景也越来越复杂,前后端的界限也越来越明确。

前端工程师只负责前端,后端工程师只负责后端。

正所谓术业有专攻如果一个人什么都会,那他就不可能什么都精通

职业划分

  • 后端java工程师

java基础,设计模式,SpringBoot,Linux,MySQL数据库,ORM框架,多线程,弹性计算架构,微服务架构(Spring Cloud),jvm性能优化,以及相关的项目管理等。

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

  • 前端工程师

html5,css3,javascipt,bootstrap,react,vue,webpack,gulp,node,多线程,模块化,面向切面编程,设计模式,浏览器兼容性,性能优化等。

前端追求的是:页面表现,速度流畅,兼容性,用户体验等。

项目解耦

几曾何时,我们的JavaWeb项目使用若干后台框架,Springmvc + Spring + Mybatis

java分层:控制层(controller),业务层(service),持久层(dao)

C层负责接收参数,调用相关业务层,封装数据,以及将数据渲染到Jsp页面

Jsp页面使用各种标签(Jstl/EL表达式/Struts标签)或者手写java表达式(<%=%>)将后台数据展现出来

项目如何发布?

将代码打成war包,然后把war包发布到web容器中(通常是Tomcat),进行启动。

然后通过配置域名,dns等等相关,网站就可以访问了

早期的开发模式,是把前后端代码放在一个地方,也就是war包。

问题:在浏览器中输入网站域名(www.xxx.com),发生了什么?

浏览器通过dns服务器,找到服务器ip,将http请求发送到服务器,在TCP3次握手之后,通过TCP协议开始传输数据,服务器得到请求后,开始提供服务,接收参数,之后响应数据到浏览器,浏览器解析数据,将其呈现给用户。

假设服务器首页中有100张图片,此时,用户点击首页,看似是一次HTTP请求。

其实并不是一次,用户在第一次访问的时候,浏览器中不会有缓存,你的100张图片,浏览器要连着请求100次HTTP请求

你的服务器接收这些请求,都需要耗费内存去创建socket来玩tcp传输(消耗服务器上的计算资源)。

重点来了,这样的话,服务器的压力会非常大。

因为页面中的所有请求都是只请求到你这台服务器上

如果1个人还好,如果10000个人并发访问呢(先不聊服务器集群,这里就说是单实例服务器)

服务器能扛住多少个TCP连接?

带宽有多大?

服务器的内存有多大?

硬盘是高性能的吗?

能抗住多少IO?

web服务器分配的内存有多大?

会不会宕机

因此,越是大中型的web应用,越要解耦

理论上,可以把数据库+应用服务+消息队列+缓存+用户上传的文件+日志等都扔在一台服务器上

你也不用玩什么服务治理,也不用做什么性能监控,什么报警机制等等,就乱成一锅粥好了。

但是这样,就好像把鸡蛋都放在一个篮子里,隐患非常大。

如果因为一个子应用的内存不稳定导致整个服务器内存溢出,那整个网站就挂了。

如果出意外挂掉,而恰好这时公司的业务处于井喷式,发展高峰期

那么恭喜你,业务成功被技术卡住,很可能会流失大量用户,后果不堪设想。

注意:技术一定要走在业务前面,否则将错过最佳的发展期

应用全部耦合在一起,相当于一个巨石

当服务端负载能力不足时,一般会使用负载均衡的方式,将服务器做成集群

这样,其实是在水平扩展一块块巨石,性能加速度会越来越低

要知道,本身负载就低的功能,完全没必要水平扩展的

本文的例子,你的性能瓶颈不在前端,何必水平扩展前端呢

还有

部署上线的时候,我明明只改了后端的代码,为什么要前端也跟着一起发布?

正常的互联网架构,是要拆开的

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,第一次运行会较慢。

5.每次请求JSP都是访问servlet再用输出流输出的html页面,效率没有直接使用html高(是每次!)。

6.JSP内有较多标签和表达式,前端工程师在修改页面时会捉襟见肘,遇到很多痛点。

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

8.需要前端工程师使用java的ide(例如eclipse),以及需要配置各种后端的开发环境,你们有考虑过前端工程师的感受吗

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

开发模式

  • 旧的开发模式
1.产品经历/领导/客户提出需求
2.UI做出设计图
3.前端工程师做html页面
4.后端工程师将html页面套成jsp页面( 前后端强依赖,后端必须要等前端的html做好才能套jsp。开发效率低)
5.集成出现问题
6.前端返工
7.后端返工
8.二次集成
9.集成成功
10.交付
  • 新的开发模式
1.产品经历/领导/客户提出需求
2.UI做出设计图
3.前后端约定接口&数据&参数
4.前后端并行开发( 如果需求变更,只要接口&参数不变,就不用两边都修改代码,开发效率高)
5.前后端集成
6.前端页面调整
7.集成成功
8.交付

请求方式

  • 旧的请求方式
1.客户端请求
2.服务端的servlet或controller接收请求( 后端控制路由与渲染页面,整个项目开发的权重大部分在后端)
3.调用service,dao代码完成业务逻辑
4.返回jsp
5.jsp展现一些动态的代码
  • 新的请求方式:
1.浏览器发送请求
2.直接到达html页面( 前端 控制路由与渲染页面 ,整个项目开发的权重前移)
3.html页面负责调用服务端接口产生数据(通过ajax等等,后台返回json格式数据)
4.填充html,展现动态效果,在页面上进行解析并操作DOM。

总结一下,新方式的请求步骤:

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

同时又可以玩分模块,还可以按业务拆成一个个的小集群,为后面的架构升级做准备。

前后分离的优势

  1. 前后端解耦,前端服务器放的是css,js,图片等一系列静态资源(甚至你还可以使用cdn加速),前端负责控制页面引用&跳转&路由,前端页面异步调用后端接口

  2. 发现bug,可以快速定位,不会出现互相踢皮球的现象,页面逻辑,跳转错误,浏览器兼容性问题,页面样式等问题,全部由前端工程师来负责。接口数据出错,数据没有提交成功,应答超时等问题,全部由后端工程师来解决。

  3. 大并发情况下,可以同时水平扩展前后端服务器,比如淘宝首页,需要2000+台前端服务器做集群来抗住数亿级别的日均pv。

  4. 减少后端服务器的并发/负载压力,理论上,除了接口以外的其他HTTP请求,应当全部转移到前端nginx上

  5. 即使后端服务暂时超时或者宕机了,前端页面也会正常访问,只不过数据刷不出来而已。

  6. 页面显示的东西再多也不怕,因为是异步加载。

  7. nginx支持热部署,不用重启服务器,前端升级更无缝。

  8. 增加代码的维护性和易读性

  9. 提升开发效率(并行开发)。

总结

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

  • 前后端工程师需要约定交互接口,实现并行开发,开发结束后需要进行独立部署

  • 前端只需要,关注页面样式与动态数据的解析&渲染,而后端专注于业务逻辑

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[透彻]为什么要前后端分离? 的相关文章

随机推荐

  • C语言—指针

    文章目录 1 指针 1 1 指针的定义 1 2 和 1 3 指针与堆内存 1 4 指针运算 1 5 常量指针与指针常量 1 5 1 常量指针 1 5 2 指针常量 1 6 函数指针 2 指针与数组 3 指针与函数 4 指针与链表 4 1 链
  • cmake中的编译选项

    CMake是一个跨平台的构建系统 它可以根据简单的配置文件生成各种平台的构建工具 例如Makefile Visual Studio项目文件等 CMake使用CMakeLists txt文件来描述项目的构建规则和依赖关系 在这个文件中 可以设
  • 浅谈opencv3.2中各个模块的简介

    3 2版本的模块说明 Opencv3 2模块 首先打开opencv modules hpp文件 可以看到对于各个功能模块的定义如下 This file defines the list of modules available in cur
  • 分享几个项目中用到的设计模式

    前言 之前项目中出于扩展性和有雅性的考虑 使用了多种设计模式进行项目框架的设计 主要的一些设计模式是单例模式 工厂模式 策略模式 责任链模式 代理模式这几种 现在依次讲讲这几个的主要是实现方式和在我们项目中的应用场景 核心设计模式分享 单例
  • WPF TextBlock 实现点击事件

    TextBlock 标签里定义MouseLeftButtonDown 事件 xaml cs
  • ICCV 2023

    ICCV 2023 MPI Flow 从单视角构建的多平面图像中学习光流 引言 主要贡献 Motivation 算法细节 Optical Flow Data Generation Independent Object Motions Dep
  • Node之使用dns模块解析域名

    引 在网络编程中 开发者更倾向于使用域名 而不是IP地址来指定网络连接的目标地址 在Node js中 提供dns模块 以实现域名查找及域名解析的处理 在dns模块中 提供了三个主方法及一系列便捷方法 其中三个主方法分别为用于将一个域名解析为
  • MySQL使用查询结果生成临时表

    MySQL中不支持对同一个表使用其查询结果更新or删除本表内数据 也就是update或delete后的where条件为针对相同表的select 解决方案是创建临时表做过度保存中间数据 可以直接使用查询结果来形成临时表 CREATE TABL
  • verilog奇数分频器的问题讲解(7分频为例)

    先不多哔哔 直接上代码 verilogHDL 代码的后面讲原理 module fenpin3 clk clk7 rst input clk rst 设置rst的目的是当rst 1的时候给cnt0和cnt1赋初值 output clk7 re
  • python sslerror_如何解决“不良握手”问题利用python请求时的SSLErrors

    I m trying to get access to the BambooHR API documentation here but I receive the following error params user username p
  • GREASELM: GRAPH REASONING ENHANCED LANGUAGE MODELS FOR QUESTION ANSWERING

    本文是LLM系列文章 针对 GREASELM GRAPH REASONING ENHANCED LANGUAGE MODELS FOR QUESTION ANSWERING 的翻译 GREASELM 图推理增强的问答语言模型 摘要 1 引言
  • 小霸王其乐无穷之函数回调

    小霸王游戏机是中国上一代备受欢迎的家用游戏机 它在1990年代初期开始流行 当时 由于游戏软件受限 国内的游戏市场相对匮乏 这使得小霸王游戏机成为许多70 80后童年时光中难忘的一部分 小霸王游戏机分为两大主要部分 游戏机本身和卡带 游戏机
  • Python中的CALL_FUNCTION指令

    在Python字节码中 CALL FUNCTION指令后跟的数字代表这次函数调用需要从栈上取出的参数的数量 具体来说 这个数字包括位置参数和关键字参数的数量 这个数字的低两位表示位置参数的数量 然后每两位表示一个关键字参数的数量 因此 如果
  • LLVM Language Reference Manual---阅读笔记

    文档地址 http llvm org docs LangRef html LLVM IR的标示符有两种基本类型 全局的和局部的 全局标示符以 开头 局部标示符以 开头 LLVM IR的标示符有三种形式 命名的 未命名的 常量 每一个Moud
  • Python pyecharts数据可视化

    Python pyecharts数据可视化 绘制精美图表 一 数据可视化 1 pyecharts介绍 2 初入了解 1 快速上手 2 简单的配置项介绍 3 案例实战 1 柱状图Bar 2 地图Map 省份 城市 地区 3 饼图Pie Pie
  • 【SMTP】【POP】电子邮件相关协议分析

    一 实验环境 通过普通路由器连接英特网的计算机一台 通过VMWare安装的Linux虚拟机一台 抓包工具 Wireshark 邮件处理软件 Foxmail 二 实验原理 SMTP工作原理 SMTP提供了一种邮件传输的机制 当收件方和发件方都
  • 公司实战 ElasticSearch+Kafka+Redis+MySQL

    一 需求 前一段时间公司要进行数据转移 将我们ES数据库中的数据转移到客户的服务器上 并且使用定时将新增的数据同步 在这过程中学到了很多 在此记录一下 二 技术栈 Mysql Redis ElasticSearch Kafka 三 方案 为
  • Ant Design Pro + Ant Design + React 踩坑记录

    1 自定义封装组件 1 1 组件通信 1 1 1 父传子 在本项目中对因为删除组件比较通用 所以对删除组件进行了封装 如下图我们对定义了通用删除组件 通过props传入回调方法 这样页面上只需要引用该组件 并传入自定义的删除函数即可引入 我
  • 单向链表实现(C语言)

    目录 一 简介 概念介绍 链接存储方法 结点结构 头指针head和终端结点 二 单向链表的使用 1 数据结构 2 从尾部添加append 3 从头部添加 add head 4 在链表任一指定位置节点按升序插入节点 5 查找并删除指定节点 6
  • [透彻]为什么要前后端分离?

    前后端分离的意义 前后端分离 已成为互联网项目开发的业界标准使用方式 前后端分离 会为以后的大型分布式架构 弹性计算架构 微服务架构打下坚实的基础 核心思想 前端页面调用后端的restuful api接口 并使用json数据进行交互 服务器