深入剖析Tomcat(十三) Host、Engine 容器

前面很多篇文章都在介绍Context与Wrapper两个容器,因为这两个容器确实也比较重要,与我们日常开发也息息相关,但是Catalina是存在四个容器的,这一章就来简单看看Host与Engine这两个容器。

再次展示下Catalina的容器结构,Engine为最顶层的容器,父容器与子容器为一对多的关系,最底层的容器为Wrapper容器,Wrapper容器不再拥有子容器。

Context容器代表一个Web应用,Wrapper容器代表Web应用中的一个servlet,那么Host与Engine代表啥呢,下面通过梳理Engine、Host与Context三者的关系来说明一下。

Host容器与Context容器

一个Tomcat中可以布有多个Web应用,也就是可以有多个Context容器实例。至于如何将请求分发到指定Context中,则是Host容器的任务了。StandardHost类是Host容器的标准实现。

下面通过一张图来展示下Host容器寻址Context容器的过程

根据uri去匹配Context容器的逻辑是一个循环判断的逻辑,代码在StandardHost#map() 方法中,下面是精简后的代码

public Context map(String uri) {Context context = null;String mapuri = uri;while (true) {context = (Context) findChild(mapuri);if (context != null) {break;}int slash = mapuri.lastIndexOf('/');if (slash < 0) {break;}mapuri = mapuri.substring(0, slash);}// 如果没有匹配上就用默认的Contextif (context == null) {context = (Context) findChild("");}return (context);}

假如请求的uri是【/app1/Primitive】,那么拿uri去匹配Context的步骤是这样的

  1. 先拿“/app1/Primitive”去匹配,没有匹配上
  2. 去掉最后的一个“/”后面的内容,uri变为“/app1”,再去匹配,匹配上了,拿到结果

如果最终也没有匹配上,就取默认的Context来用,默认Context在children中的key为空字符串。像我们使用SpringBoot开发项目的话,项目针对的Context在Host children中的key就为空字符串。

书中源码给了一个以Host为顶级容器的示例,我将启动类展示出来,感兴趣的可以下源码来自己试试

package ex13.pyrmont.startup;//explain Hostimport ex13.pyrmont.core.SimpleContextConfig;
import org.apache.catalina.*;
import org.apache.catalina.connector.http.HttpConnector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.core.StandardWrapper;
import org.apache.catalina.loader.WebappLoader;public final class Bootstrap1 {public static void main(String[] args) {//invoke: http://localhost:8080/app1/Primitive or http://localhost:8080/app1/ModernSystem.setProperty("catalina.base", System.getProperty("user.dir"));Connector connector = new HttpConnector();Wrapper wrapper1 = new StandardWrapper();wrapper1.setName("Primitive");wrapper1.setServletClass("PrimitiveServlet");Wrapper wrapper2 = new StandardWrapper();wrapper2.setName("Modern");wrapper2.setServletClass("ModernServlet");Context context = new StandardContext();// StandardContext's start method adds a default mappercontext.setPath("/app1");context.setDocBase("app1");context.addChild(wrapper1);context.addChild(wrapper2);LifecycleListener listener = new SimpleContextConfig();((Lifecycle) context).addLifecycleListener(listener);Host host = new StandardHost();host.addChild(context);host.setName("localhost");host.setAppBase("webapps");Loader loader = new WebappLoader();context.setLoader(loader);// context.addServletMapping(pattern, name);context.addServletMapping("/Primitive", "Primitive");context.addServletMapping("/Modern", "Modern");connector.setContainer(host);try {connector.initialize();((Lifecycle) connector).start();((Lifecycle) host).start();// make the application wait until we press a key.System.in.read();((Lifecycle) host).stop();} catch (Exception e) {e.printStackTrace();}}
}

Engine容器与Host容器

host,顾名思义,url中的host可以是域名也可以是ip。Host容器对应的也就是url中的host,每个Host容器实例都被安排接收其对应的“url中带有相关host的请求”。至于如何将一个请求分发到指定Host容器实例中,则是Engine容器的任务了,Engine容器是顶层容器,它不会再有父容器。StandardEngine类是Engine容器的标准实现。

如果Engine容器作为顶层容器的话,连接器则与Engine容器做关联,一个请求进来后,连接器则会将请求抛入Engine的invoke()方法,Engine再将请求给到指定的Host,Host再给到指定的Context,Context再给到指定的Wrapper,层层流转下来,请求就到达了指定的servlet中,servlet会对请求进行处理与反馈,然后将反馈结果层层上抛,最终给到连接器,连接器将结果返回给客户端,一个请求的寻址与处理流程就完成了。

我们通过一张图来展示下Engine容器寻址Host容器的过程

简单来说就是解析请求url中的host字符串,然后拿这个host字符串当做Host实例的name去 子容器map集合 "children" 中去匹配Host容器实例,匹配不上的话就用默认Host,默认Host一般为key=localhost 的这个Host。用SpringBoot开发的项目中就只有一个 key为 localhsot 的Host实例,默认Host也是它。

书中源码给了一个以Engine为顶级容器的示例,我将启动类展示出来,感兴趣的可以下源码来自己试试

package ex13.pyrmont.startup;//Use engineimport ex13.pyrmont.core.SimpleContextConfig;
import org.apache.catalina.*;
import org.apache.catalina.connector.http.HttpConnector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.core.StandardWrapper;
import org.apache.catalina.loader.WebappLoader;public final class Bootstrap2 {public static void main(String[] args) {//invoke: http://localhost:8080/app1/Primitive or http://localhost:8080/app1/ModernSystem.setProperty("catalina.base", System.getProperty("user.dir"));Connector connector = new HttpConnector();Wrapper wrapper1 = new StandardWrapper();wrapper1.setName("Primitive");wrapper1.setServletClass("PrimitiveServlet");Wrapper wrapper2 = new StandardWrapper();wrapper2.setName("Modern");wrapper2.setServletClass("ModernServlet");Context context = new StandardContext();// StandardContext's start method adds a default mappercontext.setPath("/app1");context.setDocBase("app1");context.addChild(wrapper1);context.addChild(wrapper2);LifecycleListener listener = new SimpleContextConfig();((Lifecycle) context).addLifecycleListener(listener);Host host = new StandardHost();host.addChild(context);host.setName("localhost");host.setAppBase("webapps");Loader loader = new WebappLoader();context.setLoader(loader);// context.addServletMapping(pattern, name);context.addServletMapping("/Primitive", "Primitive");context.addServletMapping("/Modern", "Modern");Engine engine = new StandardEngine();engine.addChild(host);engine.setDefaultHost("localhost");connector.setContainer(engine);try {connector.initialize();((Lifecycle) connector).start();((Lifecycle) engine).start();// make the application wait until we press a key.System.in.read();((Lifecycle) engine).stop();} catch (Exception e) {e.printStackTrace();}}
}

Engine与Host 两个容器的主要内容就是上面这些,涉及到的类也是容器老生常谈的几种类,容器标准实现类 StandardEngine,StandardHost;容器Pipeline的基础阀 StandardEngineValve,StandardHostValve;容器相关的映射器 StandardEngineMapper,StandardHostMapper,这些映射器在Tomcat4中还存在,现在使用的Tomcat版本已经不存在这些映射器了,根据请求获取Host、Context的这些逻辑都放在了request对象中来实现了。想看看源码的看看这几个类就行。

本章内容就介绍到这里,Engine与Host两个容器的功能与我们的开发工作 关联并不太多,我们了解其工作方式即可。

源码分享

https://gitee.com/huo-ming-lu/HowTomcatWorks

这一篇在源码中有两个示例,感兴趣的同学可以自己运行看看

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

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

相关文章

VS2022(Visual Studio 2022)最新安装教程

1、下载 1、下载地址 - 官网地址&#xff1a;下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux - 根据自己的电脑的 【操作系统】 灵活选择。 2、安装包 【此处为Windows系统安装包】 2、安装 1、打开软件 - 右击【以管理员身份打开】&#xff0c; 2、准备配置 …

Web Serial串口通信实现WEB浏览器读写M1卡

本示例使用的设备&#xff1a;RS232串口RFID NFC IC卡读写器可二次开发编程发卡器USB转COM-淘宝网 (taobao.com) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> &l…

优思学院|工厂的部门架构管理与精益生产

工厂内有不同部门&#xff0c;各部门之间必须协调合作才能发挥整体功能。工厂最主要的部分是制造产品的现场&#xff0c;这里安装了生产工具&#xff0c;还有操作员进行加工或生产制造。 制造时使用的材料或零组件&#xff0c;需要对外采购。对于加工组装型的工厂&#xff0c;…

基于Boost和平均电流控制方法的APFC电路设计

通过学习无线充电相关知识&#xff0c;为更快熟悉APFC工作原理&#xff0c;通过实验得以掌握 技术要求&#xff1a; 1&#xff09;输入电压&#xff1a;AC 85V&#xff5e;265V&#xff1b; 2&#xff09;输出电压&#xff1a;400V1%&#xff1b; 3&#xff09;输出额定电流…

音视频开发30 FFmpeg 视频编码- 流程以及重要API,H264编码原理说明,该章节使用h264编码说明

一.H264编码原理 1 视频为什么需要进行编码压缩 ◼ 一张为 720x480 的图像&#xff0c;用 YUV420P 的格式来表示&#xff0c;其大小为&#xff1a; 720*480*1.5 约等于 0.5MB 。 ◼ 如果是 25 帧&#xff0c; 10 分钟的数据量 0.5M*10*60*25 7500MB -> 7GB 多 ◼ …

自学网络安全的三个必经阶段(含路线图)

一、为什么选择网络安全&#xff1f; 这几年随着我国《国家网络空间安全战略》《网络安全法》《网络安全等级保护2.0》等一系列政策/法规/标准的持续落地&#xff0c;网络安全行业地位、薪资随之水涨船高。 未来3-5年&#xff0c;是安全行业的黄金发展期&#xff0c;提前踏入…

blender 快捷键 常见问题

一、快捷键 平移视图&#xff1a;Shift 鼠标中键旋转视图&#xff1a;鼠标中键缩放视图&#xff1a;鼠标滚动框选放大模型&#xff1a;Shift B线框预览和材质预览切换&#xff1a;Shift Z 二、常见问题 问题&#xff1a;导入模型成功&#xff0c;但是场景中看不到。 解…

电路与数字逻辑期末复习重点整理!!

1.带无关项的卡诺图 2.置数法设计N进制电路 计数器&#xff1a;具有记忆输入脉冲个数功能的电路称为计数器。 按照各个触发器状态更新情况的不同可分为&#xff1a; 同步计数器&#xff1a;各触发器受同一时钟脉冲─输入计数脉冲控制&#xff0c;同步更新状态。异步计数器&a…

阿里云centos 7.9 使用宝塔面板部署.netcore 6.0

前言&#xff1a; 我有一个netcore6.0的系统接口和手机端程序的站点程序之前是部署在一台windows测试服务器的IIS站点中&#xff0c; 服务器最近压力太大扛不住了&#xff0c;买了一台centos7.9的阿里云服务器准备进行迁移。具体操作日记如下。 一、安装宝塔面板 这一步涉及…

堡垒机软件详细定义以及部分厂商汇总

随着大家对网络安全的重视&#xff0c;越来越多的企业开始采购堡垒机。堡垒机可以分为硬件堡垒机、软件堡垒机、软硬一体机。今天我们就来聊聊堡垒机软件详细定义以及部分厂商汇总。 堡垒机软件详细定义 堡垒机软件&#xff0c;又称为运维安全审计系统&#xff0c;其主要功能在…

顺序表--数据结构第一关

顺序表 数据结构概念 定义&#xff1a;数据结构是计算机存储、组织数据的⽅式 根据学过C语言的基础上&#xff0c;数组是最简单的数据结构 顺序表的底层就是数组 为什么呢&#xff1f; 例子如下&#xff1a; int arr[100]{1,2,3,4,5}; //修改某一个数据&#xff1a;arr[…

【Docker】docker 替换宿主与容器的映射端口和文件路径

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 docker 替换宿主与容器的映射端口和文件夹 1. 正文 1.1 关闭docker 服务 systemctl stop docker1.2 找到容器的配置文件 cd /var/lib/docker/contain…

游戏爱好者将《超级马里奥64》移植到GBA掌机

GBA虽然在当年拥有多款马里奥系列游戏&#xff0c;不过你一定没有想到&#xff0c;N64的《超级马里奥64》也能被移植到这个游戏掌机。近日&#xff0c;一位名为Joshua Barretto的开发者就完成了这一挑战。 大家都知道&#xff0c;《超级马里奥64》于1996年登陆任天堂64主机&am…

入职必备-mac下载安装maven

1、Maven 下载 1.1、官网下载安装包 官网下载链接 历史版本下载&#xff1a; Index of /dist/maven/maven-3/3.8.8/binaries 注意 .bash_profile 文件中的符号可能会影响配置 1.2、解压文件 2、Maven 环境配置 2.1、Java JDK 依赖 配置 maven 环境变量需要先配置好 JDK …

第一视角:获取VC账号,是成为亚马逊供应商的全面准备与必要条件

在当今全球化、数字化的商业环境中&#xff0c;亚马逊作为全球最大的电子商务平台&#xff0c;为众多企业提供了无限的商业机会。然而&#xff0c;想要成功在亚马逊上立足&#xff0c;成为其优质供应商&#xff0c;并非易事。其中&#xff0c;VC(Vendor Central)账号&#xff0…

低空经济再获新动能!沃飞长空完成新一轮数亿元融资

当下&#xff0c;作为中国"新质生产力"代表的低空经济正在成为新的发展“风口”&#xff0c;全国各地开足马力加速入场。 低空经济有多“火”&#xff1f;政策方面&#xff0c;据不完全统计&#xff0c;已有26个省份的政府工作报告对发展低空经济作出部署&#xff1…

如何做好新闻软文宣发媒体资源筛选?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 新闻软文宣发是指企业通过创造或利用新闻事件&#xff0c…

使用k8s变更线上版本号

第一步&#xff0c;在镜像仓库中找到历史版本号 第二步&#xff0c;在rancher中在工作负载里 第三步&#xff0c;在rancher找到这个版本号&#xff0c;可以更改之前的版本号 这样就可以很方便的退回到之前的版本了

Django安装与启动

1、Django是什么&#xff1f; 基于python的Web开发框架&#xff0c;支持用户快速开发安全、可维护的网站 2、怎么安装&#xff1f; pip install Django4.2 3、如何启动&#xff1f; 不写ip和端口时候&#xff0c;默认启动http://127.0.0.1:8000/ python .\manage.py runse…

AI时代的量化金融:ChatGPT在交易中的应用与前景

文章目录 &#x1f4d1;前言一、智能量化&#xff1a;开启金融新世界二、作者简介三、本书特色四、适读人群 在数字化、智能化的时代浪潮中&#xff0c;金融领域正经历着一场前所未有的变革。传统的金融分析方法逐渐被高效、精准的量化金融与算法交易所替代&#xff0c;而人工智…