Tomcat外传

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

本篇开始,我们正式进入JavaWeb章节的学习。

JavaWeb阶段的学习秉持着"先松后紧、概念先行"的策略,注重帮大家理清web开发的一些概念和细节,并辅以必要的代码和案例,期望帮大家扫清犄角旮旯的一些盲点。

文章风格照旧,我们坚持实用、打好基础,以另类的角度重新复习一遍大家习以为常的知识点。

Tomcat学艺

Tomcat,熟悉的陌生人。我们所有的项目都运行在它上面,而我们却往往对它视而不见。现实中也是如此,我们周围充满了空气,我们无时无刻不在呼吸,但你从来没关心过它。同样的,Tomcat于我们而言,也只是在创建环境或者运行项目爆出各种错误时,才会去看看它。

上世纪90年代在大洋彼岸,有一家名唤SUN的公司,创造了一门全新的语言,叫Java。经过短短几年的发展,一跃成为市场上最炙手可热的语言。随后又悟出"Java13绝技",也就是所谓的JavaEE规范:JDBC,JNDI,EJB,RMI,JSP,Servlets,XML,JMS,Java IDL,JTS,JTA,JavaMail,JAF。

在大洋彼岸还有一家公司,准确来说它是一个组织,专门搞开源的,叫Apache。这家公司搞出了一个叫Tomcat的服务器。这个名字取得真好啊。中国有个词叫三脚猫,专门来吐槽别人功夫不到家。巧了,Tomcat也没完全实现JavaEE规范。13种核心技术,Tomcat只实现了俩:Servlet和JSP。而其他服务器比如JBoss、Weblogic啥的都是完全支持的。所以人们往往更愿意叫Tomcat为轻量级的服务器,也有叫它Servlet/JSP容器的。

听到这,你不禁大叫:不对啊,我记得自己写的程序里有用到JDBC啊,还可以运行哩!

啊,那是因为你导了JDBC包...但是你安装了Tomcat后另外导过Servlet/JSP的包吗?没有嘛!人家实现了Servlet/JSP规范,都整到自己源码里了。

说到这,我也是泪流满面。因为我才发现自己也是个三脚猫。上面"Java13绝技"我特么也就学过JDBC/XML/JSP/Servlet...所以我更愿意称自己是JavaWeb程序员,而不是JavaEE程序员。

我们为什么需要服务器?

在我看来,服务器最本质的作用有两个:

  • 将资源对外暴露
  • 配合各种传输协议进行响应输出

假设现在有个问题:

给你两台电脑,不通过蓝牙/QQ/微信,也不通过网盘或USB等可移动设备做中介,你要如何把一张图片从一台电脑传到另一台?

听到这个问题,我估计大部分非科班的朋友都要懵。因为如果后期没有刻意去学习计算机网络,我们对于网络的了解基本仅限于基础班4小时的"网络编程"讲解。而大家平时又太习惯地址栏键入"www.baidu.com",无脑一回车就上网冲浪了。现在突然让你去访问隔壁的电脑,确实有点束手无策。

解决这个问题的方法可能有多种,这里介绍其中一种:通过服务器访问。

请先了解以下三个概念:

  • IP:电子设备(计算机)在网络中的唯一标识,一个IP对应一台实体电脑
  • 端口:应用程序在计算机中的唯一标识,一个端口只能被唯一程序占用
  • 传输协议:数据传输的规则

中国有14亿人口,每个人都有唯一的身份标识:身份证,用以精确定位某个个体。同样的,网络上有几十亿台电脑,每台电脑都有自己的一串特有IP(不同局域网内可以相同),也就是说一个IP代表一台特定的实体电脑。比如《唐伯虎点秋香》中华安的编号是9527,而华府的管家从不叫他名字,而是直接喊"9527"。因为"9527"就是华安。

虽然根据IP可以精准定位一台电脑,但是还不足以让我们访问这台电脑。就好比你知道了我的门牌号,但是我没给你开门。所谓的门,就是一个端口,而端口的背后是应用程序。

一般来说,一个端口可以定位一个软件,但一个软件可以占用多个端口(你家的门,只属于你家,但可以有前后门)。在现实生活中,你家的门如果被别人占用了或者堵了,客人(请求)就进不去了。而在程序中,如果有两个程序的端口相同,就会发生端口冲突,也就是所谓的"端口占用"。端口占用的后果往往是程序无法启动,更遑论运行。

关于端口,再举个例子:

微信和QQ都是腾讯公司的,你的电脑上同时装了这两个软件。为什么我用QQ给你发消息,你的微信收不到?

正常人看起来很傻的问题,实际上并不是那么简单。

每个应用程序都有自己的端口号(可能有多个),它们一旦运行,就要去监听这些端口。每个程序都是电脑的囚犯,看不到外面的世界,而端口就是给这些囚犯送饭的窗口。应用程序们整天躲在电脑里盯着自己的端口们,祈求着别的计算机来访时能送个大鸡腿(Request请求)。

其实QQ这些软件属于C/S架构,已经为我们屏蔽了太多底层,什么IP、端口全部都是自动封装的。相比来说,B/S架构更直观一些。比如用浏览器访问百度:

想要访问一台服务器,必须知道它的IP。但我们人类不擅长记忆长串数字,于是人类搞了所谓的域名来指向IP。但实际请求时,最终还是要换算成IP去访问。总得来说有两种换算的途径:

  • 本机的hosts文件
  • DNS服务器

不知道有没有细心的朋友注意到了下面的细节:

即使DNS解析域名得到对应的IP后,Request请求里还是会带上host。为什么?

因为:域名!=IP。

实际上一个IP可以对应多个域名。也就是说一台实体服务器(大铁柜) ,理论上可以有多个域名(虚拟主机)。 实体服务器和网站是两个概念。IP只是对应实体服务器,而域名对应具体的网站。

比如上面百度服务器,虽然看起来115.239.210.27这个IP完全等同于.baidu.com,但也有可能这个IP对应的服务器上配置了两个虚拟主机:www.baidu.comtieba.baidu.com。所以即使找到了IP对应的服务器实体,Request请求还是要带上host主机名,以确定是哪个虚拟主机。

通过DNS解析域名得到IP,然后根据IP+host找到服务器

另外,如果两个域名对应同一个IP,那么必须设置其中一个域名为默认的,不然同一台服务器有两个虚拟主机,我该访问谁?

已经知道IP,就无需DNS解析,可直接访问服务器。若这个IP对应的服务器有两个虚拟主机,而用户Request请求行中又没有指定host,则会访问默认主机(因此服务器要事先指定默认主机!Tomcat默认localhost)

最后,再用Tomcat举个例子。比如,现在我有一台笔记本电脑(一个实体服务器),它的本机IP是192.168.112.1,我在上面装了Tomcat。如果Tomcat不改动配置,则默认只有一个虚拟主机localhost(默认主机)。接着我开发了一个JavaWeb程序demo1部署到Tomcat,然后我同事在浏览器输入下方地址:

复制代码
192.168.112.1:8080/demo1/index.html

访问我的电脑。虽然没有带host,但是localhost是默认的,于是访问它。

不过,上面的百度服务器只是举个例子,实际上百度搜索和百度贴吧的IP是不同的,也就是说它们不在同一台服务器上。通常来说,一个IP对应一台服务器,服务器上只有一个主机,拿到IP基本就可以确定要访问哪个网站。

3个容易混淆的小概念

我们经常开口闭口"服务器"、"服务器"的,其实"服务器"是个很容易引发歧义的概念,我能想到的就有3点:

  • 软件概念的服务器和硬件概念的服务器
  • Web服务器?Web容器?
  • 我们开发的Web应用都是半成品!

软件概念的服务器和硬件概念的服务器

软件概念上,只要是一台硬件配置正常、装有操作系统、插着电能上网,并且安装特定软件的电脑,都可以称为服务器。比如你要学习数据库了,于是你装了MySQL服务端,那么此时你的电脑就是一个MySQL服务器。然后你又装了SVN服务端,那么此时你的电脑既是MySQL服务器,又是SVN服务器。Tomcat服务器同理。

硬件概念上,服务器本质上也是一台电脑,只不过配置高的同时长相丑了点,基本就是一个冰冷的大铁柜。我们的笔记本电脑既能看片又能玩游戏,而它们基本上专机专用。

Web服务器?Web容器?

其实,Tomcat服务器 = Web服务器 + Servlet/JSP容器(Web容器)。

Web服务器的作用是接收客户端的请求,给客户端作出响应。但是很明显,服务器不止静态资源呀,所以客户端发起请求后,如果是动态资源,Web服务器不可能直接把它响应回去(比如JSP),因为浏览器只认识静态资源。所以对于JavaWeb程序而言,还需要JSP/Servlet容器,**JSP/Servlet容器的基本功能是把动态资源转换成静态资源。**我们JavaWeb工程师需要使用Web服务器和JSP/Servlet容器,而通常这两者会集于一身,比如Tomcat。

Web服务器接收、响应客户端请求,Web容器装载Servlet/JSP,让它们去处理动态资源

所以刚才我们画的百度服务器,其实细节还可以更丰满些:

我们开发的Web应用都是半成品!

我们写代码的时候,都知道相同代码最好抽取成公共方法以复用。现在我们来想一想,上百上千的Web应用有什么共性吗?

首先,资源肯定不同,无法抽取。比如优酷主打视频,知乎基本都是文字。

其次,业务也肯定不同,比如百度主要是搜索,淘宝是电商。但是有一点是一样的,这些网站都需要"接收用户请求"+"响应用户请求"。

嗯?桥多麻袋!!这两个概念,好像哪里见过!不错,就是上面的Web服务器。仔细回想一下,我们开发JavaWeb时,你操心过如何接收HTTP请求和响应HTTP请求吗?显然没有嘛!因为你一直忙着debug。所以,我们用Java开发的Web应用只是一个半成品,类似于一个插件,而服务器则像一个收发器:

什么是动态资源?

其实对于何谓动态资源,我也没有很精准的概念。要讲清楚一个东西是什么,有时是比较难的事。不如先说它不是什么。

**动态资源不等同于动态页面。**所谓动态页面,就是页面会动,而会动的页面不一定是动态资源。比如我可以用JQuery执行一段代码,让一个Div不断放大缩小,但是很显然它还是一个HTML页面。

**所谓动态资源,其实最显著的特征就是它能动态地生成HTML!**比如JSP。动态资源有个"特色":它的数据是"可拼装"的、而且"可以随时间变化"。下面用号称可以抗住8个明星同时出轨的新浪服务器举个例子:

突然,新浪《花花世界》专栏的小编发现,原来和smart哥有绯闻的不是刘亦菲,而是佟丽娅,于是打开专栏做了修改:

此时,粉丝们再次打开《花花世界》专栏,看到的就是:佟丽娅深夜买醉smart哥。

上面这个例子很好地说明了动态资源(JSP)的两个特性:

  • 可拼装:${name}"深夜买醉smart哥"
  • 随时间变化:刘亦菲→佟丽娅

那么为什么说HTML就是静态资源呢?我也可以修改HTML页面使它发生改变啊!很好,很有想法。那么请小编先学会Linux,然后远程连接服务器进入到Tomcat目录下修改吧。

动态资源和静态资源虽然都在服务器里,但是动态资源包含变量("可拼装"特性),而变量维系着数据库和程序之间的联系。

如果把JSP比作电子广告牌,变量比作一根电线,而电线连接着一台电脑(数据库服务器)。那么只要电脑上重新编辑文本,广告牌的内容也会变,此谓动态。而静态资源就像一张布告,当初写什么就是什么,任他风吹雨打,都不会再改变了。

动手实现"Tomcat"

最后,还有个很无聊的问题留给大家思考:JavaSE阶段,我们无论做什么,都是上来先敲main()。学了JavaWeb后,我想问问,你有多久没敲main()了?她去哪了呢?

来找smart哥要视频!

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

进群,大家一起学习,一起进步,一起对抗互联网寒冬

相关推荐
坐吃山猪3 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫4 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao4 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区5 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT6 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy6 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss8 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续8 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0448 小时前
ReAct模式解读
java·ai