写过后端的同学都有过这样的体验:既要写后端接口,返回数据;又要写前端页面,展示数据。既要写java、mysql、Oracle等,又要写html、css、js、jquery、ajax。
慢慢的,许多大中小公司开始把前后端的界限分的越来越明确,前端工程师只管前端的事情,后端工程师只管后端的事情。在大中型公司中非常明显,大公司需要专业人才;而小公司需要全才,前后端都要懂。样样通的结果就是样样松,对个人的发展不利。专业细化的社会需要高精尖专业人才,从个人角度来说,也应把精力放在自己专业的方向上,术业有专攻,这样你的核心竞争力才会越来越高。
对于后端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多线程,模块化,面向切面编程,设计模式,浏览器兼容性,性能优化等等。
前端追求的是:页面表现,速度流畅,兼容性,用户体验等等。
什么是前后端分离?
前后端分离,一句话总结就是后端负责数据,前端负责显示。
前后端分离并非仅仅只是一种开发模式,而是一种架构模式(前后端分离架构)。千万不要以为只有在写代码的时候把前端和后端分开就是前后端分离了,需要区分前后端项目,前端项目与后端项目是两个项目,放在两个不同的服务器,需要独立部署,两个不同的工程,两个不同的代码库,不同的开发人员。
前后端工程师需要约定交互接口,实现并行开发,开发结束后需要进行独立部署,前端通过 ajax 来调用 http 请求调用后端的 restful api。
前端只需要关注页面的样式与动态数据的解析渲染,而后端专注于具体业务逻辑。
为什么要前后端分离?
解耦
一般的 JavaWeb 项目都是使用了若干后台框架,springmvc/struts + spring + spring jdbc/hibernate/mybatis 等等。大多数项目在java后端都是分了三层,控制层(controller/action),业务层(service/manage),持久层(dao)。控制层负责接收参数,调用相关业务层,封装数据,以及路由渲染到jsp页面。然后jsp页面上使用各种标签(jstl/el/struts标签等)或者手写java表达式(<%=%>)将后台的数据展现出来。这种情况下的代码耦合性很强,前后端代码全都打在一个war包,部署在一个web容器(tomcat/jboss/weblogic/websphere/jetty/resin)里。
这样一来,服务器被用户访问时的压力会非常大,因为所有请求都是只请求到你这台服务器上,所有全部都耦合在一起,相当于一个巨石,当服务端负载能力不足时,一般会使用负载均衡的方式,将服务器做成集群,这样其实你是在水平扩展一块块巨石,性能加速度会越来越低,本身负载就低的功能模块是没有必要水平扩展的。还有发版部署上线的时候,我明明只改了后端的代码,为什么要前端也跟着发布呢?
正常的互联网架构,是都要拆开的,你的web服务器集群,你的应用服务器集群+文件服务器集群+数据库服务器集群+消息队列集群+缓存集群等等。
JSP 的痛点
以前的 javaWeb 项目大多数使用jsp作为页面层展示数据给用户,因为流量不高,因此也没有那么苛刻的性能要求,但现在是大数据时代,对于互联网项目的性能要求是越来越高,因此原始的前后端耦合在一起的架构模式已经逐渐不能满足我们,因此我们需要需找一种解耦的方式,来大幅度提升我们的负载能力。
- 动态资源和静态资源全部耦合在一起,服务器压力大,因为服务器会收到各种http请求,例如css的http请求,js的,图片的等等。
一旦服务器出现状况,前后台一起玩完,用户体验极差。 - UI出好设计图后,前端工程师只负责将设计图切成html,需要由java工程师来将html套成jsp页面,出错率较高(因为页面中经常会出现大量的js代码),修改问题时需要双方协同开发,效率低下。
- jsp 必须要在支持 java 的 web 服务器里运行(例如tomcat,jetty,resin等),无法使用nginx等(nginx据说单实例http并发高达5w,这个优势要用上),性能提不上来。
- 第一次请求jsp,必须要在web服务器中编译成servlet,第一次运行会较慢。
- 每次请求jsp都是访问servlet再用输出流输出的html页面,效率没有直接使用html高。
- jsp内有较多标签和表达式,前端工程师在修改页面时会捉襟见肘,遇到很多痛点。
- 如果jsp中的内容很多,页面响应会很慢,因为是同步加载。
前后端分离的好处
- 可以实现真正的前后端解耦,前端服务器使用nginx。
- 发现bug,可以快速定位是谁的问题,不会出现互相踢皮球的现象。
- 在大并发情况下,我可以同时水平扩展前后端服务器。
- 减少后端服务器的并发/负载压力。
- 即使后端服务暂时超时或者宕机了,前端页面也会正常访问,只不过数据刷不出来而已。
- 也许你也需要有微信相关的轻应用,那样你的接口完全可以共用,如果也有app相关的服务,那么只要通过一些代码重构,也可以大量复用接口,提升效率。(多端应用)
- 页面显示的东西再多也不怕,因为是异步加载。
- nginx支持页面热部署,不用重启服务器,前端升级更无缝。
- 增加代码的维护性、易读性(前后端耦在一起的代码读起来相当费劲)。
- 提升开发效率,因为可以前后端并行开发,而不是像以前的强依赖。
- 在nginx中部署证书,外网使用 https 访问,并且只开放 443 和 80 端口,其他端口一律关闭(防止黑客端口扫描),内网使用http,性能和安全都有保障。
- 前端大量的组件代码得以复用,组件化,提升开发效率。
怎么做前后端分离?
大方向就是
后端专注于:后端控制层(Restful API) & 服务层 & 数据访问层;
前端专注于:前端控制层(Nodejs) & 视图层
本人认为的前后端分离模式应该是这样:
1、项目设计阶段,前后端架构负责人将项目整体进行分析,讨论并确定API风格、职责分配、开发协助模式,确定人员配备;设计确定后,前后端人员共同制定开发接口。
2、项目开发阶段,前后端分离是各自分工,协同敏捷开发,后端提供Restful API,并给出详细文档说明,前端人员进行页面渲染前台的任务是发送API请求(GET,POST等)获取数据(json,xml)后渲染页面。
3、项目测试阶段,API完成之前,前端人员会进行模拟测试,后端人员采用junit进行API单元测试,不用互相等待;API完成之后,前后端再对接测试一下就可以了,当然并不是所有的接口都可以提前定义,有一些是在开发过程中进行调整的。
4、项目部署阶段,利用nginx 做反向代理,即Java + nodejs + nginx 方式进行。