跳转至

01 Web容器学习路径

你好,我是李号双。在开篇词里我提到要成长为一名高级程序员或者架构师,我们需要提高自己知识的广度和深度。你可以先突破深度,再以点带面拓展广度,因此我建议通过深入学习一些优秀的开源系统来达到突破深度的目的。

我会跟你一起在这个专栏里深入学习Web容器Tomcat和Jetty,而作为专栏更新的第1篇文章,我想和你谈谈什么是Web容器,以及怎么学习Web容器。根据我的经验,在学习一门技术之前,想一想这两个问题,往往可以达到事半功倍的效果。

Web容器是什么?

让我们先来简单回顾一下Web技术的发展历史,可以帮助你理解Web容器的由来。

早期的Web应用主要用于浏览新闻等静态页面,HTTP服务器(比如Apache、Nginx)向浏览器返回静态HTML,浏览器负责解析HTML,将结果呈现给用户。

随着互联网的发展,我们已经不满足于仅仅浏览静态页面,还希望通过一些交互操作,来获取动态结果,因此也就需要一些扩展机制能够让HTTP服务器调用服务端程序。

于是Sun公司推出了Servlet技术。你可以把Servlet简单理解为运行在服务端的Java小程序,但是Servlet没有main方法,不能独立运行,因此必须把它部署到Servlet容器中,由容器来实例化并调用Servlet。

而Tomcat和Jetty就是一个Servlet容器。为了方便使用,它们也具有HTTP服务器的功能,因此Tomcat或者Jetty就是一个“HTTP服务器 + Servlet容器”,我们也叫它们Web容器。

其他应用服务器比如JBoss和WebLogic,它们不仅仅有Servlet容器的功能,也包含EJB容器,是完整的Java EE应用服务器。从这个角度看,Tomcat和Jetty算是一个轻量级的应用服务器。

在微服务架构日渐流行的今天,开发人员更喜欢稳定的、轻量级的应用服务器,并且应用程序用内嵌的方式来运行Servlet容器也逐渐流行起来。之所以选择轻量级,是因为在微服务架构下,我们把一个大而全的单体应用,拆分成一个个功能单一的微服务,在这个过程中,服务的数量必然要增加,但为了减少资源的消耗,并且降低部署的成本,我们希望运行服务的Web容器也是轻量级的,Web容器本身应该消耗较少的内存和CPU资源,并且由应用本身来启动一个嵌入式的Web容器,而不是通过Web容器来部署和启动应用,这样可以降低应用部署的复杂度。

因此轻量级的Tomcat和Jetty就是一个很好的选择,并且Tomcat它本身也是Spring Boot默认的嵌入式Servlet容器。最新版本Tomcat和Jetty都支持Servlet 4.0规范。

读到这里,我想你应该对Web容器有了基本的认识,可以结合平时工作再去细细体会一下。如果你对HTTP协议和Servlet依然是一头雾水,不用担心,在预习模块中我还会和你聊聊你应该掌握的HTTP协议和Servlet的相关知识,帮你打好学习的基础。

Web容器该怎么学?

Java Web技术发展日新月异,各种框架也是百花齐放。在从事Java Web开发相关的工作时,面对这些眼花缭乱的技术时你是否会感到一丝迷茫?可能有些初学者不知道从哪里开始,我身边还有些已经进入了这个行业,并且有了一定Java基础的人,对于系统设计的体会可能还不够深刻,编程的时候还停留在完成功能的层次。这样不仅业务上难有突破,对于个人成长也很不利。

为了打破这个瓶颈,就需要我们在深度上多下功夫,找准一个点,深挖下去,彻底理解它的原理和设计精髓。并且在深入学习Tomcat和Jetty这样的Web容器之前,你还需要掌握一定的基础知识,这样才能达到事半功倍的效果。

下面我列举一些在学习Web容器之前需要掌握的关键点,我建议你在学习专栏的同时,再去复习一下这些基础知识。你可以把这些基础知识当作成为架构师的必经之路,在专栏以外也要花时间深入进去。当然为了让你更好地理解专栏每期所讲的内容,重点的基础知识我也会在文章里帮你再梳理一遍。

操作系统基础

Java语言其实是对操作系统API的封装,上层应用包括Web容器都是通过操作系统来工作的,因此掌握相关的操作系统原理是我们深刻理解Web容器的基础。

对于Web容器来说,操作系统方面你应该掌握它的工作原理,比如什么是进程、什么是内核、什么是内核空间和用户空间、进程间通信的方式、进程和线程的区别、线程同步的方式、什么是虚拟内存、内存分配的过程、什么是I/O、什么是I/O模型、阻塞与非阻塞的区别、同步与异步的区别、网络通信的原理、OSI七层网络模型以及TCP/IP、UDP和HTTP协议。

总之一句话,基础扎实了,你学什么都快。关于操作系统的学习,我推荐你读一读《UNIX环境高级编程》这本经典书籍。

Java语言基础

Java的基础知识包括Java基本语法、面向对象设计的概念(封装、继承、多态、接口、抽象类等)、Java集合的使用、Java I/O体系、异常处理、基本的多线程并发编程(包括线程同步、原子类、线程池、并发容器的使用和原理)、Java网络编程(I/O模型BIO、NIO、AIO的原理和相应的Java API)、Java注解以及Java反射的原理等。

此外你还需要了解一些JVM的基本知识,比如JVM的类加载机制、JVM内存模型、JVM内存空间分布、JVM内存和本地内存的区别以及JVM GC的原理等。

这方面我推荐的经典书籍有《Java核心技术》《Java编程思想》《Java并发编程实战》《深入理解Java虚拟机:JVM高级特性与最佳实践》等。

Java Web开发基础

具备了一定的操作系统和Java基础,接下来就可以开始学习Java Web开发,你可以开始学习一些通用的设计原则和设计模式。这个阶段的核心任务就是了解Web的工作原理,同时提高你的设计能力,注重代码的质量。我的建议是可以从学习Servlet和Servlet容器开始。我见过不少同学跳过这个阶段直接学Web框架,这样做的话结果会事倍功半。

为什么这么说呢?Web框架的本质是,开发者在使用某种语言编写Web应用时,总结出的一些经验和设计思路。很多Web框架都是从实际的Web项目抽取出来的,其目的是用于简化Web应用程序开发。

我以Spring框架为例,给你讲讲Web框架是怎么产生的。Web应用程序的开发主要是完成两方面的工作。

  • 设计并实现类,包括定义类与类之间的关系,以及实现类的方法,方法对数据的操作就是具体的业务逻辑。
  • 类设计好之后,需要创建这些类的实例并根据类与类的关系把它们组装在一起,这样类的实例才能一起协作完成业务功能。

就好比制造一辆汽车,汽车是由零件组装而成的。第一步是画出各种零件的图纸,以及定义零件之间的接口。第二步把把图纸交给工厂去生产零件并组装在一起。因此对于Web应用开发来说,第一步工作是具体业务逻辑的实现,每个应用都不一样。而第二步工作,相对来说比较通用和标准化,工厂拿到零件的图纸,就知道怎么生产零件并按照零件之间的接口把它们组装起来,因此这个工作就被抽取出来交给Spring框架来做。

Spring又是用容器来完成这个工作的的,容器负责创建、组装和销毁这些类的实例,而应用只需要通过配置文件或者注解来告诉Spring类与类之间的关系。但是容器的概念不是Spring发明的,最开始来源于Servlet容器,并且Servlet容器也是通过配置文件来加载Servlet的。你会发现它们的“元神”是相似的,在Web应用的开发中,有一些本质的东西是不变的,而很多“元神”就藏在“老祖宗”那里,藏在Servlet容器的设计里。

Spring框架就是对Servlet的封装,Spring应用本身就是一个Servlet,而Servlet容器是管理和运行Servlet的,因此我们需要先理解Servlet和Servlet容器是怎样工作的,才能更好地理解Spring。

本期精华

今天我谈了什么是Web容器,以及该如何学习Web容器。在深入学习之前,你需要掌握一些操作系统、Java和Web的基础知识。我希望你在学习专栏的过程中多温习一下这些基础知识,有扎实的基础,再结合专栏深入学习Web容器就比较容易了。

等你深刻理解了Web容器的工作原理和设计精髓以后,你就可以把学到的知识扩展到其他领域,你会发现它们的本质都是相通的,这个时候你可以站在更高的角度来学习和审视各种Web框架。虽然Web框架的更新比较快,但是抓住了框架的本质,在学习的过程中,往往会更得心应手。

不知道你有没有遇到过这样的场景,当你在看一个框架的技术细节时,会突然恍然大悟:对啊,就是应该这么设计!如果你有这种感觉,说明你的知识储备起到了作用,你对框架的运用也会更加自如。

课后思考

请你分享一下你对Web容器的理解,或者你在学习、使用Web容器时遇到了哪些问题?

不知道今天的内容你消化得如何?如果还有疑问,请大胆的在留言区提问,也欢迎你把你的课后思考和心得记录下来,与我和其他同学一起讨论。如果你觉得今天有所收获,欢迎你把它分享给你的朋友。

精选留言(15)
  • 蔡伶 👍(66) 💬(1)

    打卡 先说下听完老师课程的感受:经典不会随着时间而消逝。java和servlet规范已经发布20多年、操作系统和网络协议以及html更是经过了几十年的洗礼,现在依然是业内最核心的技术基础,毫不动摇。 课程的理解:当前web技术涉及的知识包括这样几层, 第一层:核心规范相当于宪法,主要包括servlet规范、网络协议等; 第二层:主流技术支撑相当于各类法律,包括java语言、各类中间件等; 第三层:基于各行业的业务应用和框架,相当于行政法规地方法规。 规范是基础,具体实现可以用java也可以用python等等,行业应用和框架更是可以百花齐放。 那我们的学习一定是从具体技术入手,从规范和体系结构统筹安排,最后再落实到实现。是一个自底向上再由上向下的一个过程,也是一个由薄到厚再由厚到薄的过程。

    2019-05-15

  • 今夜秋风和 👍(43) 💬(3)

    应用程序的上下文,这个概念总是感觉理解不透彻

    2019-05-14

  • G 👍(35) 💬(1)

    你说的所有spring. 都应该说springMVC

    2019-05-13

  • 贤蛋蛋 👍(30) 💬(2)

    请问为什么说http是超文本传输协议,文本两字的含义是什么?http2.0所说的二进制帧,为什么说是二进制,和1.1格式上的本质区别是什么?再往下一层到TCP能否都看成二进制帧?

    2019-05-15

  • 凌霄 👍(25) 💬(1)

    遇到过一个偶发的tomcat8问题,请求到tomcat后,nio长连接,到了20秒后超时后才自动断开连接,返回结果内容正常,抓包发现和正常的比少了最后的回车换行。

    2019-05-14

  • 飞向云端 👍(12) 💬(1)

    什么叫内嵌方式运行servlet容器,老师有时间普及一下。

    2019-05-19

  • yy_java 👍(6) 💬(1)

    请问老师,操作系统基础 除了您推荐的那本书以外还有其他薄点的书籍推荐吗?

    2019-05-18

  • 拒绝 👍(6) 💬(2)

    还停留在使用容器的阶段,并不清楚其原理,例如:一个请求到一个响应返回,其涉及到的设计模式,以及为什么这样做,这样做的好处是什么;我能在容器的基础上做一些自定义的扩展吗?希望在专栏收获到这些。

    2019-05-13

  • chibohe 👍(4) 💬(1)

    如果我的服务全都是rpc调用,不涉及http调用,可以不部署在tomcat或者jetty容器中吗?还有你说的Spring都应该指的是SpringMVC吧?

    2019-05-27

  • Monday 👍(4) 💬(1)

    操作系统还是我的痛,但也不是一两天就能补充得了的。只好边学本专栏边学操作系统了。希望不要因为操作系统的缘故拖了学习本专栏的后腿😃😃

    2019-05-16

  • Jaswine 👍(4) 💬(1)

    带着问题学知识,学习的时候问自己几个为什么,为什么这么设计?为什么不那么设计?在自己解答这些为什么的时候,最后发现都是计算机基础知识决定的,操作系统,网络,数据结构和算法

    2019-05-15

  • 刘三通 👍(3) 💬(1)

    Spring应用本身就是一个Servlet容器

    2019-05-19

  • 小可爱(๑• . •๑) 👍(3) 💬(1)

    期待不断更新,希望老师能够讲清楚,让大家都理解

    2019-05-14

  • 不负 👍(2) 💬(1)

    Web容器通常具备 HTTP 服务器和 Servlet 容器的功能,Tomcat 和 Jetty 是其经典代表。 Servlet 容器:部署和启动 Web 应用的环境。 1)文中提到的“嵌入式Web容器”,是已经不依赖外部容器,项目本身(具备Servlet功能)部署到一个HTTP服务器即可启动? 2)web服务器就是一个HTTP服务器?

    2019-05-14

  • 贾智文 👍(1) 💬(1)

    想问下为什么内嵌的web容器会更加简单?

    2019-06-24