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.com和tieba.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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/187601.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue中data为什么是一个函数

vue中的data是一个对象类型,对象类型的数据是按引用传值的,这就会导致所有组件的实例都共享同一份数据,这是不对的,我们要的是每个组件实例都是独立的 为了解决对象类型数据共享的问题,我们需要将 data 定义成一个函数…

C++11线程以及线程同步

C11中提供的线程类std::thread,基于此类创建一个新的线程相对简单,只需要提供线程函数和线程对象即可 一.命名空间 this_thread C11 添加一个关于线程的命名空间std::this_pthread ,此命名空间中提供四个公共的成员函数; 1.1 get_id() 调用命名空间s…

Python自动化测试——元素定位

1.selenium简介 Selenium是一个用于Web应用程序测试的工具。Selenium是直接运行在浏览器中,模拟用户操作web界面。支持多平台:windows、linux、MAC ,支持多浏览器:ie、firefox、chrome等浏览器。 2. 启动浏览器 # 导入webdrive…

JavaWeb服务器详解和后端分层解耦

JavaWeb HTTP协议请求数据格式响应数据格式协议解析 Web服务器请求响应请求参数的接收响应 分层解耦IOC&DI入门IOC详解 HTTP协议 超文本传输协议,规定了浏览器和服务器之间数据传输的规则 特点: 基于TCP协议:面向连接,安全 …

【Android知识笔记】架构专题(二)

分层架构概论 分层的依据是什么? 关注点分离:自下而上,从机器到用户,从抽象到具体,从通用到业务,每一层,各自关注各自的抽象层次。修改与影响:不同层之间的代码或技术方案修改,彼此互不影响。例如 UI 界面从 xml 布局改成 Jetpack Compose 之后,不应该影响数据层。换…

【android开发-03】android中Intent的用法介绍

1,Intent的作用 在Android开发中,Intent的使用非常广泛,包括启动Activity、启动Service、发送广播等。是各组件间交互的一种重要方式,他不仅可以指明当前组件想要执行的动作,还可以在不同组件间传递数据。 Intent可以…

kafka中的常见问题处理

文章目录 1. 如何防⽌消息丢失2. 如何防⽌重复消费3. 如何做到消息的顺序消费4. 如何解决消息积压问题4.1 消息积压问题的出现4.2 消息积压的解决⽅案 5. 实现延时队列的效果5.1 应用场景5.2 具体方案 1. 如何防⽌消息丢失 ⽣产者:1)使⽤同步发送 2&…

thinkphp 判断当前页 导航条高亮等方法

ACTION_NAME等表示全局变量,表示当前页面的操作方法 APP_NAME // 当前项目名称 MODULE_NAME //当前模块名称 ACTION_NAME // 当前操作名称 当然,也可以在控制器中,自己定义变量,比如 $this->assign(‘nav’, ‘cp’); 用法示例 <li <if condition" (ACTION_NA…

uniapp使用u-checkbox

当使用uni-app开发时&#xff0c;可以使用u-checkbox组件来实现复选框功能。以下是一个更详细的例子&#xff0c;展示如何在uni-app中使用u-checkbox组件&#xff0c;并介绍一些相关的API用法。 首先&#xff0c;确保已经安装并引入了u-checkbox组件。可以通过在页面的<tem…

NetApp EF 系列全闪存存储,为实时分析、HPC 和数据库等性能敏感型工作负载提供助力

NetApp EF 系列全闪存存储 如果您需要为实时分析、HPC 和数据库等性能敏感型工作负载提供强劲动力&#xff0c;NetApp EF 系列全闪存存储的性价比优势不言自明。其可为要求最苛刻的应用程序提供微秒级响应&#xff0c;最大限度地延长正常运行时间并提供 99.9999% 的可靠性。 为…

Maya 2024(3D建模、动画和渲染软件)

Maya 2024是一款非常强大的3D建模、动画和渲染软件&#xff0c;它提供了许多新功能和改进&#xff0c;以帮助建模师、动画师和渲染师更加高效地进行创作。 在建模方面&#xff0c;Maya 2024引入了Symmetry&#xff08;对称&#xff09;功能&#xff0c;可以在网格两侧生成均匀…

学习笔记三十六:通过Ingress-nginx实现灰度发布

通过Ingress-nginx实现灰度发布 灰度发布原理将新版本灰度给部分用户切一定比例的流量给新版本 部署两个版本的服务以 nginx 为例&#xff0c;先部署一个 v1 版本:部署一个 v2 版本再创建一个 Ingress&#xff0c;对外暴露服务&#xff0c;指向 v1 版本的服务:访问验证 基于 He…

智能井盖位移报警器效果一览,感知井盖异常

井盖位移是指井盖在受到外力作用下产生的位置移动。这种现象通常发生在道路颠簸、车流量较大或地下管道受压较大的区域&#xff0c;当然也不排除会出现在一些角落内。当井盖发生位移或倾斜时&#xff0c;不仅会影响城市内道路的通行&#xff0c;还会给行人和车辆带来安全隐患。…

1056 Mice and Rice

题意&#xff1a;给定一组选手&#xff0c;按一定顺序将这些选手进行分组竞赛&#xff0c;每组的最大值为优胜者&#xff0c;进入下一轮分组再进行竞赛&#xff0c;直到选出最大值。然后输出每个选手的rank。 坑点&#xff1a;每个选手的rank为该轮竞赛选出的优胜者数1&#x…

web:catcat-new(文件包含漏洞、flask_session伪造)

前提知识 /etc/passwd 该文件储存了该Linux系统中所有用户的一些基本信息&#xff0c;只有root权限才可以修改。其具体格式为 用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell&#xff08;以冒号作为分隔符&#xff09; /proc/self proc是一个伪文件系统…

【前缀和]LeetCode1862:向下取整数对和

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 给你一个整数数组 nums &#xff0c;请你返回所有下标对 0 < i, j < nums.length 的 …

Java之Stream的实用语法

1. 转Map List<Book> books bookMapper.list(); Map<String, Book> bookMap books.stream().collect(Collectors.toMap(Book::getBookId, book -> book));结果结构 {"1": {"bookId": "1","bookTitle": "书1&q…

2-redis高级-centos上安装redis(编译安装、redis启动)、redis客户端操作、redis使用场景、redis中的通用命令

1 centos上安装redis 1.1 编译安装 1.2 redis启动 2 redis客户端操作 3 redis使用场景 4 通用命令 1 centos上安装redis # win 上装redis # 上线--》centos装了--》详细研究 # docker 装---》配置--》持久化# 官网看看-redis源码 -----》自己编译-redis stack----》编译过后的…

LangChain的函数,工具和代理(二):LangChain的表达式语言(LCEL)

LangChain Expression Language (LCEL) 是 LangChain 工具包的重要补充&#xff0c;旨在提高文本处理任务的效率和灵活性。LCEL 允许用户采用声明式方法来组合链&#xff0c;便于进行流处理、批处理和异步任务。其模块化架构还允许轻松定制和修改链组件。LCEL 的优势之一是它使…

知识图谱最简单的demo实现——基于pyvis

1、前言 我们在上篇文章中介绍了知识图谱的简单实现&#xff0c;最后使用neo4j进行了展示&#xff0c;对于有些情况我们可能并不想为了查看知识图的结果再去安装一个软件去实现&#xff0c;那么我们能不能直接将三元组画出来呢/ 接下来我们就介绍一个可视化的工具pyvis&#…