Web技术概述 Last updated: 2022-08-12 14:39:22
前言
1. 前言
SpringBoot目前是Web开发领域的事实上的王者。其实,要完成一个Web项目的开发,可选的方案还是非常多的,那为什么就基于Java的SpringBoot就成了目前的权威呢?这是因为它足够简单,同时又足够复杂,足够强大,同时又足够优秀。 - 足够简单,是说它的许多地方,约定大于配置,即:大约都按这个约定这样写,不必手动配置这个配置那个,所以,简单省事。 - 足够复杂,是说它虽然约定大于配置,但是如果你想自己定制许多配置,个性化许多东西,你还是可以做到的,它是支持的。当然了,配置起来还是很复杂的。 - 足够强大,是说它具备一般Web应用的所有优秀特质:常驻内存、多线程并行并发、编译执行、快速扩容等。SpringBoot程序开发好部署启动之后,它会常驻内存,每个请求进来之后分配一个线程去处理和响应请求,它不会像CGI或Fast-CGI一样,每次一个请求进来都要现启一个进程来处理请求,这会很响应很慢而开销很大,另外就是SpringBoot2是基于JDK8的,它在运行较长时间之后,热点代码会被由字节码编译成原生代码直接执行,效率会越来越高。至于快速扩容嘛,只要你代码没写废,启一个后台进来如果因为用户量数据量太大撑不住了,快速启几个,组成一个微服务或分布式集群,就能快速提升系统容量,完成扩容。 - 足够优秀,是因为SpringBoot确实是一个非常优秀的框架,它为我们程序员做了许多许多事情,让我们可以直接上手开发业务,不必再关心其他系统层级的许多问题。
2. Web开发史
基于Java的Web开发史,说起来还是蛮有意思的。我简单地分将其为四代技术,第一代技术,就是基于Java的原生Web开发技术,第二代技术是基于Spring框架的Web开发技术,第三代是通过SSM整合开发技术,第四代就是现在这套SpringBoot全自动开发技术。可以看出,开发技术是越来越厉害越来越省事了,但是缺点也不是没有,那就是底层封装越来越复杂,要掌握和理解底层原理以及排查一些错误和故障,难度非常之大了。
2.1 Java原生Web开发
最早的时候, 我们的先辈们都是使用Java原生Web开发技术的。说这个技术之前,我们先说什么是Servlet。Servlet是一套服务器端程序扩展规范,最早由Java语言的开发商SUN公司(后来被Oracle公司收购)设计开发出来。这句话看似简单,理解透它不容易,它有两层意思,一是Servlet是一套规范,二是说它是服务器端程序扩展的规范。
在Servlet出现之前,我们的服务器网页应用程序(也就是Web应用、万维网互联网应用程序),都是静态的,开发一堆静态的HTML、CSS、图片等,放到服务器上,然后用Web服务器Nginx或apache或IIS加载并响应给客户端浏览器。这种静态Web开发技术,缺点是很明显的,它不能完成一些动态内容的处理,比如一个商城想要计算分析用户下单购买相关情况等等,就实现不了。
所以,就出现了CGI技术,CGI是Common Gateway Interface的简写,它是一套Web服务器运行外部程序的规范,是的,CGI也是一套规范,它的重点就是“Web服务器运行外部程序”,既然Web服务器可以运行外部程序了,那么我们让浏览器把用户的输入提交上来,我们再让Web服务器程序转发给外部程序,然后让外部程序运行,完成计算,然后把计算结果返回给浏览器(在这个过程中还可以把相关数据保存到数据库中去),这样就实现了动态内容动态计算。如下图所示:
当然了,这个Web服务器调用和执行外部程序,并将结果返回回来,再进一步返回给用户端,这有一整套规范的,什么类型的数据往哪里放,怎么传,都有规定(所以才是CGI规范嘛)。让Web应用的内容支持动态,这是互联网应用开发技术的一大创举,具有划时代的意义。但是,这个CGI并非没有缺点,当有许多许多个用户端的时候,服务器每次处理请求,都要启动一个外部程序来处理,这个开销是非常大的,服务器很容易受不了而当机,或者需要购买很多服务器用很多CPU和内存才能满足用户需求,成本太高了。所以,紧接着又出来了一个Fast-CGI。
Fast-CGI和CGI相比,最大的变动是将外部程序这个环节,变成了一个进程池,并加入了缓存、进程间通信(主要用于解决数据一致性问题)等技术。当Web服务器启动时,预先加载一个进程管理器,进程管理器再加载若干个目标外部程序,形成一个进程池,当请求进来时,即时从池中取一个进程来处理用户请求。所以,它可以轻松实现高并发,以这种模式开发的Web应用程序,并发能力是比较强的,程序的容量也高,服务器的成本大幅下降。如下图所示:
CGI、Fast-CGI是和语言无关的,这个规范和流程中的外部程序或外部程序池,可以是任何语言开发的程序,比如C、C++、Python、PHP等等,相比之下,使用PHP的是比较多的,管理多个PHP进程池的,叫PHP-fpm。
PHP、PHP-fpm、apache服务器三者之间互相支持,协同工作的很好,同时PHP又很容易地支持快速简单地操作MySQL数据库,所以,在很长一段时间里,使用PHP做Web开发是很流行的,这套技术栈就叫LAMP(Linux、apache、MySQL、PHP),现在也有许多人用,堪称黄金搭档。
CGI并非一无是处,一是它足够简单,配置和部署很容易,二是它是单点的外部程序模式,当程序中有错误或疑惑的地方时,排查起来是非常方便的,很容易就能找到问题出在哪里并快速排除故障。Fast-CGI也并非优秀到了极致,至少和CGI相比,排除和解决问题的难度上升了,进程间通信也复杂,多个请求同时修改一份数据时,很容易出现的数据冲突也需要额外的技术来解决。
💊Fast-CGI技术虽然也有缺点,但它相比于后来的许多Web开发技术,既不那么复杂,并发能力又强,这才是它这么多年经久不衰的原因。因为它在软件开发成本、软件开发效率、服务器硬件成本、运行效率、动态能力、软件维护成本等多个方面处于一个比较均衡的状态。
Servlet的出现,是对CGI、Fast-CGI的继承和发展,它仍然是为了解决Web应用程序中的一个核心问题:动态内容交给谁去执行计算任务并返回结果。Servlet规范中,最重要的一个创新的思想,就是容器。容器,是一个为相关程序组件提供运行环境的程序。是的,容器本身也是一个程序,只不过它是用来给我们开发的程序提供运行环境和支持的(你可以认为它做的事情有点像虚拟机,虽然这么理解不是很准确,但是我们姑且认为这没有什么大毛病)。Servlet中还有两个非常重要的机制,一个是生命周期,另一个是扩展功能。生命周期是指Servlet应用程序的工作过程,主要有初始化(init方法)、处理请求(service方法)、销毁(destroy方法)三个阶段。
使用Java基于Servlet开发应用程序其实也很简单,只要继承并实现Servlet中的几个主要方法,就可以了。它的核心思想是实现了Java语言中的监听客户端请求的ServerSocket,在Java程序中,预置一个线程池,当有一个请求进来时,ServerSocket的accept方法就触发,得到一个输入流(里面是客户端请求进来的数据),将这个请求交给一个线程去处理,处理完了将响应回给请求者就可以了。这样就实现了常驻内存、监听端口、响应请求的完整过程。Servlet就是对这个过程进行抽象、封装和定义规范。Tomcat、JBoss都是非常优秀的Servlet容器,它们自带了一套优秀的Servlet规范的实现,使得我们可以直接使用它们提供的能力,快速完成业务功能的开发。
为了实现对大规模、超大规模的服务器端应用程序的支持,SUN公司(后来的Oracle公司)及其社区的人们发现,仅有Servlet是不够的,于是又逐渐发展出了许多专用于服务器端的基于Java的软件开发技术,叫做J2EE,它主要包含JDBC(用于实现Java操作数据库)、JNDI(用于存取企业级的资源)、EJB(用来封装企业级的业务逻辑)、RMI(用于在分布式环境下实现远程方法调用)、JSP(使用Java代码生成HTML资源)、JMS(用于消息通信)、JTS(用于处理事务)等等。
2.2 Spring Web开发
基于Servlet开发Web应用程序已经很容易了,但是,现代Web应用程序的规模越来越大,所有业务逻辑和代码功能都放在Servlet中进行处理和管理,程序的灵活性、扩展性、可维护性都越来越受到了挑战。这种情况下,许多开发框架应运而生,如Webwork、Structs、SpringMVC、JFinal等等。其实又以SpringMVC应用最为广泛。
2.3 SSM整合开发
SSM就是Spring、SpringMVC、MyBatis。
我们先说Spring。前文我们说过,为了应对大规模超大规模的现代Web应用程序开发,SUN公司和社区搞出来一套J2EE,最开始开发J2EE的初衷是好的,它将Java在服务器端(也就是企业级应用)的相关技术都包含进去了,规划的很好,但是在实践中,大家更加倾向于能够以简洁的代码快速搭建一个易于使用、易于维护、易于测试的框架并快速开始业务功能的开发。所以,Spring框架也就应运而生了。从这里我们可以看出,J2EE其实就是一个典型的学术派,它在一定程度上脱离了现实,当然了,J2EE也并非一无是处,它的许多设计思想对于我们后面的软件开发技术的发展和进步还是很有指导意义的,这个我们后面再说。
Spring框架的设计初衷,是作为一个轻量级的、灵巧的中间件存在,它不打算替换现有的开发技术,也无意于取代Web服务器,而是整合企业级应用开发中的表现层、业务层和持久层,然后与Web服务器及Servlet以及现有的Web开发技术进行无缝整合,例如它还可以整合Structs、Hibernate、Hessian、Quartz、MyBatis等。可以说,这样的设计出发点是非常切合实际的,它基于容器管理各个对象,基于XML配置各个组件,使用IoC管理各个组件之间的依赖,使用AOP以非侵入式技术使得各业务逻辑之间既能协同工作又充分解藕,又对视图层、业务逻辑层和数据访问对象(DAO)提供了完整的支持。所有Spring的这些特征都使开发人员能够快速编写更干净、更可管理、并且更易于测试的代码。所以,甫一面世,便封神作。
SpringMVC是一个全功能的、用于构建Web应用程序的框架,它在Spring这套Web开发技术的基础之上,完成了一套非常优秀的MVC的实现(MVC是一种软件开发思想,它将软件开发中的视图、模型、控制器进行分离,这样就能将数据和视图进行分离,使用控制器进行调度,使得应用程序更加灵活和易于扩展,同时也便于并行开发和维护。MVC和语言无关,PHP、.Net等语言中也有MVC的优秀设计)。所以流行了十多年之久。
凡事都有两面性,Spring、SpringMVC虽然优秀,但是也并非没有缺点,它采用这种实用、灵活的技术完成了对Web开发领域的各个技术的整合和接入,使得广大开发人员不必学习一门全新的开发技术才能完成任务,这是它非常受欢迎的根本。但是在这个过程中,非常多的配置、非常多的组件管理、非常多的功能模块,也对开发提出了新的挑战。
2.4 SpringBoot全自动开发
以Spring、SpringMVC做Web应用程序开发,就像搭积木一样,将自己需要用到的组件整合进来,配置好,然后就可以快速的编写具体的业务逻辑代码了。但是事情的发展是永无止境的,大规模超大规模企业级应用中,集成的组件多、业务模块多,在配置整合好各个组件,然后才能开始业务功能的开发,这是非常麻烦的一件事情,所以,基于自动配置的SpringBoot来了,它本质上是只是对SpringMVC的二次封装和优化,但是它最大的改变就是将许多原来要手动配置的地方,全都搞成了自动化,有一套默认的自动配置、自动扫描、自动初始化、自动装配、自动加载、甚至自动执行。总而言之,已经达到了傻瓜式的地步。
💡Spring和SpringMVC就好比最早的专业相机,功能虽然强大,但是要发挥了它巨大的威力,我们还需要自己学习研究怎么掌握它精通它,而SpringBoot就好像是单反傻瓜式相机,啥也不需要配了,快门一键,照片就出来了。好处是显而易见的,那就是快速开发一个应用程序很容易,缺点也很明显,对底层的封装太彻底了,当我们要理解和掌握它的底层原理的时候,或者要排查一些和底层相关的问题的时候,其实是非常困难的。
入门应用
建设中…