当前位置: 首页 > Web前端 > vue.js

为什么Javaweb项目要抛弃JSP而拥抱前后端分离?

时间:2023-03-31 20:39:45 vue.js

看到一篇很不错的博文,JavaWeb项目为什么要放弃jsp呢?为什么要解耦前后端?为什么要分离前后端?2.0版为分布式架构奠定了基础。博主杨明涵的发言特别通透全面。特此转载分享。另外,这篇博文对原文进行了小幅的重新编排,使文章的结构更加清晰易读。一、前言前后端分离已经成为互联网项目开发的行业标准使用方式。通过nginx+tomcat(或者中间可以加一个nodejs)可以实现有效的解耦,前后端分离为未来的大规模分布式架构、弹性计算架构、微服务架构、多端服务(多客户端,如浏览器、车载终端、Android、IOS等)打下了坚实的基础。这一步是系统架构从猿进化到成人的必由之路。核心思想是前端html页面通过ajax调用后端的restufulapi接口,与json数据进行交互。在互联网架构中,名词解释:Web服务器:泛指nginx、apache之类的服务器,一般只能解析静态资源。应用服务器:泛指tomcat、jetty、resin等服务器,既能解析动态资源,也能解析静态资源,但解析静态资源的能力不如web服务器。一般外网只能访问web服务器,内网只能访问应用服务器。第二,技术行业专业化(开发人员分离)。之前的JavaWeb项目,大多都是当爹当妈的java程序员,搞前端,搞后端。随着时代的发展,渐渐的很多大中小公司开始把前后端的界限划分得越来越清晰。前端工程师只管前端的事,后端工程师只管后端的事。正所谓艺术行业是有专精的,如果一个人什么都会,那终究不是什么都会。大中型公司需要专业人才,小公司需要多面手,但是为了个人的职业发展,我建议分开。1、面向java后端工程师:重点学习java基础、设计模式、jvm原理、spring+springmvc原理及源码、linux、mysql事务隔离与锁机制、mongodb、http/tcp、多线程、分布式架构、弹性计算架构、微服务架构、java性能优化,以及相关的项目管理等。后端追求的是:三高(高并发、高可用、高性能)、安全、存储、业务等等。2、前端工程师:关注html5、css3、jquery、angularjs、bootstrap、reactjs、vuejs、webpack、less/sass、gulp、nodejs、GoogleV8引擎、javascript多线程、模块化、面向切面编程、设计模式、浏览器兼容性、性能优化等。前端追求的是:页面性能、流畅速度、兼容性、用户体验等。美术行业有专攻,这样你的核心竞争力就会越来越高。俗话说,你在生活中投入什么,生活会回报你。而且两端的发展越来越先进。如果你什么都能想到,那你终究是什么都不擅长。通过将团队划分为前端和后端团队,双方工程师可以专注于各自领域,独立管理,进而打造全栈卓越团队。3、在原始人时代(各种耦合),我们的JavaWeb项目使用了几个后台框架,如springmvc/struts+spring+springjdbc/hibernate/mybatis等。大多数项目在java后端分为三层,控制层,业务层,持久层。控制层负责接收参数,调用相关业务层,封装数据,路由渲染到jsp页面。然后在jsp页面使用各种标签或者手写java表达式来显示后台数据,玩MVC的思路。我们先来看这种情况:需求定了,代码写好了,测试完了,然后呢?是不是要发布了?你需要用maven或者eclipse等工具把你的代码打包成war包,然后把war包发布到你生产环境的web容器中,对吧?发布后,您需要启动您的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传输(消耗服务器上的计算资源)。重点来了,这种情况下你服务器的压力会很大,因为页面中所有的请求都只请求到你的服务器,一个人还好,10000人并发访问怎么办(先不说服务器优先)集群,这里是单实例服务器),你的服务器可以处理多少个tcp连接?你的带宽有多大?你的服务器有多少内存?你的硬盘是高性能的吗?你能抵抗多少IO?您为Web服务器分配了多少内存?会不会降?这就是为什么,越是大中型的Web应用,越是需要解耦。理论上,你可以把你的数据库+应用服务+消息队列+缓存+用户上传文件+日志+等丢在一台服务器上,不需要玩任何服务治理,也不需要做性能监控,什么报警机制之类的,就乱七八糟了。但这就像把所有的鸡蛋都放在一个篮子里,隐患很大。如果由于某个子应用内存不稳定导致整个服务器内存溢出导致饥饿,那么你的整个网站就会挂掉。如果你意外挂了,此时你的业务正处于井喷发展的高峰,那么恭喜你,你的业务成功被技术卡住了,可能会流失大量用户,后果不堪设想。(注意:技术一定要走在业务前面,否则你会错过最好的发展期,亲~)另外,你的应用都是耦合在一起的,相当于一块巨石。当服务器负载能力不足时,一般采用负载均衡的方式将服务器做成集群。这样一来,你实际上是在横向扩展巨石,性能加速会越来越低。要知道,负载小的功能或模块是不需要横向扩展的。是的,本文的例子是你的性能瓶颈不在前端,那为什么要横向扩展前端呢???还有,版本发布部署上线的时候,我明明只改了后端代码,为什么前端也要发布???正常的互联网架构一定要拆解,你的web服务器集群,你的应用服务器集群+文件服务器集群+数据库服务器集群+消息队列集群+缓存集群等等。4.JSP的痛点以前的javaWeb项目大多都是用jsp作为页面层向用户展示数据,因为当时流量不高,所以没有那么苛刻的性能要求,但是现在是大数据时代,互联网项目对性能的要求越来越高。因此,原有的前后端耦合在一起的架构模型已经逐渐不能满足我们了,所以我们需要找到一种解耦的方式来大幅提升我们的负载能力。1、动态资源和静态资源都耦合在一起,服务器压力很大,因为服务器会收到各种http请求,比如http请求css、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、前端工程师需要使用javaide(如eclipse),需要配置各种后端开发环境。考虑过前端工程师的感受吗?基于以上的一些痛点,我们应该将整个项目的开发重心前移,实现前后端真正的解耦!5、开发模式老办法是:1、产品体验/领导力/客户要求2、UI设计图3、前端工程师制作html页面4、后端工程师将html页面设置成jsp页面(前端和前端强依赖,后端必须等前端html准备好后才能应用jsp,如果html改了就更痛苦,开发效率低)。集成成功10.新交付方式为:1.产品体验/领导力/客户需求2.UI设计图3.前后端约定接口&数据&参数4.前后端并行开发(无强依赖,可以前后端并行开发,如果需求发生变化,只要接口&参数不变,无需修改两边代码,开发效率高)5.前后端整合6.前端页面调整7.整合成功方法是:1.客户端请求2.服务端的servlet或controller接收到请求(后端控制路由和渲染页面,大部分整个项目开发的重心都在后端)3.调用service,dao代码完成业务逻辑4.回归jsp5,jsp中显示一些动态代码的新方式是:1.浏览器发送请求2.直接到达htmlpage(前端控制路由和渲染页面,将整个项目开发的权重前移)3.html页面负责调用服务端接口生成数据(通过ajax等,后台返回json格式的数据,json数据格式代替xml,因为它简单高效)4.填写html,显示动态效果,分析操作页面DOM。总结一下新方法的请求步骤:大量并发浏览器请求—>web服务器集群(nginx)—>应用服务器集群(tomcat)—>文件/数据库/缓存/消息队列服务器集群可以打分模块在同时,也可以按业务拆分成小集群,为后续的架构升级做准备。七、前后端分离的优点1、可以实现真正的前后端解耦,前端服务器使用nginx。前端/WEB服务器放css、js、图片等一系列静态资源,服务器负责控制页面引用&跳转&路由。前端页面异步调用后端接口,后端/应用服务器使用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、召开需求会议时,所有前端和前端工程师都必须参加,需要制定接口文档。后端工程师一定要写测试用例(二维),不要让前端工程师充当你的专职测试人员,推荐使用chrome插件postman或者soapui或者jmeter,service层的测试用例都是junit写的。ps:前端也能玩单元测试吗?2、上面的接口不是java中的接口。说白了,调用接口就是调用你控制器中的方法。3.增加了前端团队的工作量,减少了后端团队的工作量,提高了性能和扩展性。4、我们需要一些前端框架来解决页面嵌套、分页、页面跳转控制等功能。(上面提到的那些前端框架)。5.如果你的项目很小,或者是纯内网项目,那你大可放心,不需要任何架构,但是如果你的项目是外网项目,嘿嘿嘿。6.以前有人用velocity/freemarker之类的模板框架生成静态页面。7、这篇文章的主要目的是说jsp在大型外网javaweb项目中被淘汰,但并不是说jsp完全不能学。对于一些同学朋友来说,jsp/servlet等相关的javaweb基础还是需要学习的。抓牢它,不然你以为springmvc的框架是靠什么做的?8、如果页面上有一些权限等相关检查,那么这些相关数据也可以通过ajax从界面获取。9、可以在前端或者后端做的逻辑,我建议放在前端。为什么?因为你的逻辑是需要计算资源来计算的,如果放在后端运行逻辑,会消耗带宽、内存、cpu等计算资源,你要记住,服务器端的计算资源是有限的,而如果放在前端,使用客户端的计算资源,这样你的服务端负载就会下降(高并发场景)。类似于数据校验,前后端都要做!10、前端需要有处理后端请求超时和后端服务宕机的机制,并友好的展示给用户。九。延伸阅读1.其实js、css、图片等静态资源可以认为是放在一个类似于阿里云的oss的文件服务器上(如果是普通的服务器&操作系统,可以存放PB级)级文件之后,或者单个文件夹的文件数达到30000-50000,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测试(构建虚拟测试对象模拟后端,可独立开发测试),后端需要有详细的测试用例,保证可用性和服务的稳定性。10.总结前后端分离不仅仅是一种开发模式,更是一种架构模式(前后端架构分离)。不要以为只写了代码就把前后端分开了,需要区分前后端项目。前端项目和后端项目是两个项目,分别放在两台不同的服务器上,需要独立部署,两个不同的项目,两个不同的代码库,不同的开发者。前端和后端工程师需要在交互界面上达成一致,以实现并行开发。开发完成后,需要独立部署。前端使用ajax调用http请求调用后端的restfulapi。前端只需要关注页面的样式和动态数据的解析渲染,后端关注具体的业务逻辑。注:本文转载,原文地址:JavaWeb项目为什么我们要放弃jsp?为什么要解耦前后端?为什么要分离前后端?2.0版为分布式架构奠定了基础。