https://developer.51cto.com/art/202001/608984.htm

把你的精力专注在java,jvm原理,spring原理,mysql锁,事务,多线程,大并发,分布式架构,微服务,以及相关的项目管理等等,这样你的核心竞争力才会越来越高,正所谓你往生活中投入什么,生活就会反馈给你什么。

满满的正能量:

一旦你成为了一个行业里的精英,相信我,到时候,车,房,女人,钱,机会就都来找你了,不用着急,真的。

干java程序猿这行,真的很简单的,你懂得知识越多,你的钱就越多,当然了还需要有一定的情商。。。

你的能力越强,你就比别人创造的价值更多,你为公司创造了价值,公司给你各种福利,双赢!)

几曾何时,我们的java web项目都是使用了若干后台框架,springmvc/struts + spring + spring jdbc/hibernate/mybatis 等等

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

控制层负责接收参数,调用相关业务层,封装数据,以及路由到jsp页面。然后jsp页面上使用各种标签(jstl/el)或者手写java(<%=%>)将后台的数据展现出来。

对吧?

我们先看这种情况,需求定完了,代码写完了,测试测完了,然后呢?要发布了吧?

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

发布完了之后,你要启动你的web容器,开始提供服务,这时候你通过配置域名,dns等等相关,你的网站就可以访问了(假设你是个网站)。

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

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

我捡干的说了啊,基础不好的童鞋请自己去搜。

浏览器在通过ip路由到你的服务,在tcp3次握手之后,通过tcp协议开始访问你的web服务器,你的web服务器得到请求后,开始提供服务,接收请求,之后通过response返回你的应答给浏览器。

那么我们来看,我们先假设你的首页中有100张图片,以及一个单表的查询,此时,用户的看似一次http请求,其实并不是一次,用户在第一次访问的时候,浏览器中不会有缓存,你的100张图片,浏览器要连着请求100次http请求(有人会跟我说http长链短链的问题,不在这里讨论),你的web服务器接收这些请求,都需要耗费内存去创建socket来玩tcp传输。

重点来了,这样的话,你的web服务器的压力会非常大,因为页面中的所有请求都是只请求到你这台服务器上,如果1个人还好,如果10000个人并发访问呢(先不聊web服务器集群,这里就说是单实例web服务器),那你的服务器能扛住多少个tcp链接?你的服务器的内存有多大?你能抗住多少IO?你给web服务器分的内存有多大?会不会宕机?

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

理论上你可以把你的数据库+应用服务+消息队列+缓存+用户上传的文件+日志+等等都扔在一台主机上,但是这样就好像是你把鸡蛋都放在一个篮子里,隐患非常大。

正常的分布式架构,是都要拆开的,你的应用服务器集群(前,后)+文件服务器集群+数据库服务器集群+消息队列集群+缓存集群等等。

前戏太长了。

MVC

下面步入正题,首先以后的java web项目都尽量要避免使用jsp,要搞前后台解耦,玩分布式架构,这样我们的应用架构才更强。

使用jsp的痛点:

  1. 动态资源和静态资源全部耦合在一起,无法做到真正的动静分离。服务器压力大,因为服务器会收到各种http请求,例如css的http请求,js的,图片的,动态代码的等等。一旦服务器出现状况,前后台一起玩完,用户体验极差。
  2. 前端工程师做好html后,需要由java工程师来将html修改成jsp页面,出错率较高(因为页面中经常会出现大量的js代码),修改问题时需要双方协同开发,效率低下。
  3. jsp必须要在支持java的web服务器里运行(例如tomcat等),无法使用nginx等(nginx据说单实例http并发高达5w,这个优势要用上),性能提不上来。
  4. 第一次请求jsp,必须要在web服务器中编译成servlet,第一次运行会较慢。
  5. 每次请求jsp都是访问servlet再用输出流输出的html页面,效率没有直接使用html高。
  6. jsp内有较多标签和表达式,前端工程师在修改页面时会捉襟见肘,遇到很多痛点。
  7. 如果jsp中的内容很多,页面响应会很慢,因为是同步加载。

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

以前老的方式是:

  1. 客户端请求
  2. 服务端的servlet或controller接收请求(路由规则由后端制定,整个项目开发的权重大部分在后端)
  3. 调用service,dao代码完成业务逻辑
  4. 返回jsp
  5. jsp展现一些动态的代码

新的方式是:

  1. 浏览器发送请求
  2. 直接到达html页面(路由规则由前端制定,整个项目开发的权重前移)
  3. html页面负责调用服务端接口产生数据(通过ajax等等)
  4. 填充html,展现动态效果。

(有兴趣的童鞋可以访问一下阿里巴巴等大型网站,然后按一下F12,监控一下你刷新一次页面,他的http是怎么玩的,大多数都是单独请求后台数据,使用json传输数据,而不是一个大而全的http请求把整个页面包括动+静全部返回过来)

这样做的好处是:

  1. 可以实现真正的前后端解耦,前端服务器使用nginx。前端服务器放的是css,js,图片等等一系列静态资源(甚至你还可以css,js,图片等资源放到特定的文件服务器,例如阿里云的oss,并使用cdn加速),前端服务器负责控制页面引用,跳转,调用后端的接口,后端服务器使用tomcat。(这里需要使用一些前端工程化的框架比如nodejs,react,router,react,redux,webpack)
  2. 发现bug,可以快速定位是谁的问题,不会出现互相踢皮球的现象。页面逻辑,跳转错误,浏览器兼容性问题,脚本错误,页面样式等问题,全部由前端工程师来负责。接口数据出错,数据没有提交成功,应答超时等问题,全部由后端工程师来解决。
  3. 双方互不干扰,前端与后端是相亲相爱的一家人。
  4. 在大并发情况下,我可以同时水平扩展前后端服务器,比如淘宝的一个首页就需要2000台前端服务器做集群来抗住日均多少亿+的日均pv。(去参加阿里的技术峰会,听他们说他们的web容器都是自己写的,就算他单实例抗10万http并发,2000台是2亿http并发,并且他们还可以根据预知洪峰来无限拓展,很恐怖,就一个首页。。。)
  5. 减少后端服务器的并发压力,除了接口以外的其他所有http请求全部转移到前端nginx上。
  6. 即使后端服务暂时超时或者宕机了,前端页面也会正常访问,只不过数据刷不出来而已。
  7. 也许你也需要有微信相关的轻应用,那样你的接口完全可以共用,如果也有app相关的服务,那么只要通过一些代码重构,也可以大量复用接口,提升效率。
  8. 页面显示的东西再多也不怕,因为是异步加载。

注意:

  1. 在开需求会议的时候,前后端工程师必须全部参加,并且需要制定好接口文档,后端工程师要写好测试用例,不要让前端工程师充当你的组专职测试,推荐使用chrome的插件postman,service层的测试用例拿junit写。
  2. 上述的接口并不是java里的interface,说白了调用接口就是调用你controler里的方法。
  3. 加重了前端团队的工作量,减轻了后端团队的工作量,提高了性能和可扩展性。
  4. 我们需要一些前端的框架来解决类似于页面嵌套,分页,页面跳转控制等功能。(上面提到的那些前端框架)。
  5. 如果你的项目很小,或者是一个单纯的内网项目,那你大可放心,不用任何架构而言,但是如果你的项目是外网项目,呵呵哒。
  6. 以前还有人在使用类似于velocity/freemarker等模板框架来生成静态页面,现在这种做法也被淘汰掉了。
  7. 最后:这篇文章主要的目的是说jsp在大型外网java web项目中被淘汰掉,可没说jsp可以完全不学,对于一些学生朋友来说,jsp/servlet等相关的java web基础还是要掌握牢的,不然你以为SpringMVC这种框架是基于什么来写的?

转载:把你的精力专注在java,jvm原理,spring原理,mysql锁,事务,多线程,大并发,分布式架构,微服务,以及相关的项目管理等等,这样你的核心竞争力才会越来越高的更多相关文章

  1. Java互联网架构-直播互动平台高并发分布式架构应用设计

    概述 网页HTML 静态化: 其实大家都知道网页静态化,效率最高,消耗最小的就是纯静态化的 html 页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法, ...

  2. 资深P7架构师详解淘宝服务端高并发分布式架构演进之路

    1. 概述 本文以淘宝作为例子,介绍从一百个并发到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则. ...

  3. 不懂这些高并发分布式架构、分布式系统的数据一致性解决方案,你如何能找到高新互联网工作呢?强势解析eBay BASE模式、去哪儿及蘑菇街分布式架构

    互联网行业是大势所趋,从招聘工资水平即可看出,那么如何提升自我技能,满足互联网行业技能要求?需要以目标为导向,进行技能提升,本文主要针对高并发分布式系统设计.架构(数据一致性)做了分析,祝各位早日走上 ...

  4. 服务端高并发分布式架构 ESB 企业服务总线

    服务端高并发分布式架构演进之路 - 个人文章 - SegmentFault 思否 https://segmentfault.com/a/1190000018626163 ESB 企业服务总线讲解 ht ...

  5. 服务端高并发分布式架构演进之路 转载,原文地址:https://segmentfault.com/a/1190000018626163

    1. 概述 本文以淘宝作为例子,介绍从一百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则. 特 ...

  6. Java架构技术进阶之:从分布式到微服务,深挖Service Mesh

    自从几十年前第一次引入分布式系统这个概念以来,出现了很多原来根本想象不到的分布式系统使用案例,但同时也引入了各种各样的新问题. 当这些系统还是比较少比较简单的时候,工程师可以通过减少远程交互的次数来解 ...

  7. Java Jvm运行机制原理

    一:简介 在学习Java虚拟机之前,也就是Jvm之前,我想大家能够带着问题去学习,这样的话,大家学习起来也会比较有所获! 1.Java虚拟机(Jvm)是什么? 2.Java虚拟机是用来干什么的? 3. ...

  8. Java基础(spring事物和锁)

    使用步骤: 步骤一.在spring配置文件中引入<tx:>命名空间<beans xmlns="http://www.springframework.org/schema/b ...

  9. 使用Redis实现高并发分布式序列号生成服务

    序列号的构成 为建立良好的数据治理方案,作数据掌握.分析.统计.商业智能等用途,业务数据的编码制定通常都会遵循一定的规则,一般来讲,都会有自己的编码规则和自增序列构成.比如我们常见的身份证号.银行卡号 ...

随机推荐

  1. 丢弃掉那些BeanUtils工具类吧,MapStruct真香!!!

    在前几天的文章<为什么阿里巴巴禁止使用Apache Beanutils进行属性的copy?>中,我曾经对几款属性拷贝的工具类进行了对比. 然后在评论区有些读者反馈说MapStruct才是真 ...

  2. java 封装与this关键字

    一 封装 1.封装的概述 封装,它也是面向对象思想的特征之一.面向对象共有三个特征:封装,继承,多态. 封装表现: 1.方法就是一个最基本封装体. 2.类其实也是一个封装体. 从以上两点得出结论,封装 ...

  3. 高级搜索树-AVL树

    目录 平衡因子 AVL树节点和AVL树的定义 失衡调整 插入和删除操作 完整源码 AVL树是平衡二叉搜索树中的一种,在渐进意义下,AVL树可以将高度始终控制在O(log n) 以内,以保证每次查找.插 ...

  4. C#算法设计排序篇之06-堆排序(附带动画演示程序)

    堆排序(Heap Sort) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/685 访问. 堆排序是指利用堆积树(堆)这 ...

  5. LeetCode 122 best-time-to-buy-and-sell-stock-ii 详解

    题目描述 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你 ...

  6. day7 地址 名片管理系统

    1 无限循环  (while  True)   break 退出     人为设计的 ,并且有退除的出口      死循环 bug  错误 2.引用   数字型

  7. 编译hotspot8

    编译hotspot8 ubuntu desktop 18 全新准备与编译过程再记录下: # 建议使用此gcc和g++版本,过高版本比如gcc7或引发编译报错 sudo apt-get install ...

  8. 【源码】RocketMQ如何实现获取指定消息

    概要 消息查询是什么? 消息查询就是根据用户提供的msgId从MQ中取出该消息 RocketMQ如果有多个节点如何查询? 问题:RocketMQ分布式结构中,数据分散在各个节点,即便是同一Topic的 ...

  9. 深入源码理解Spark RDD的数据分区原理

    通过内存创建RDD的分区设置 1.示例代码 在创建RDD的时候,我们可以从内存中进行创建:输出保存为文件.为了演示效果,我们的示例代码如下: import org.apache.spark.{Spar ...

  10. JavaScript学习系列博客_14_JavaScript中对象的基本操作

    对象的基本操作 - 创建对象 - 方式一:使用new关键字调用的函数,是构造函数(constructor),构造函数是专门用来创建对象的函数. var obj = new Object(); - 方式 ...