tomcat组件-Server

news/2024/7/8 0:22:26

目录

概述

tomcat 启动 大致流程

Server

StandardServer

利用8005端口关闭tomcat

总结


概述

了解一个程序,一定要知道他是干什么的,以及内部架构如何支撑这么干的,以及牵扯的到的概念、模式等知识点的解析(这里只介绍组件)。

Tomcat是Apache 开发的Web 应用服务器,支持最新的Servlet 和JSP 规范,servlet jsp是 J2EE里的规范。

学习tomcat组件,有助于指定tomcat启动的流程以及初始化的时候做了哪些工作,为后续请求和响应做准备。

组件从配置的地方来看比较好理解,tomcat核心配置文件是/config/server.xml,如果对配置了解不足,就无法对组件进行探讨。

源码版本:apache-tomcat-8.5.84-src

下载地址:​​​​​​https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.84/src/apache-tomcat-8.5.84-src.zip

tomcat 启动 大致流程

一图胜千言,先不管为啥,先看启动过程

Server

一个Server 就是一个tomcat,一个tomcat实例只能有一个server

其中 8005是tomcat监听关闭的端口号,如果socket监听到接受到了字符串SHUTDOWN,则关闭tomcat具体实现类是StandardServer它内部包含多个Service,代码体现:

private Service services[] = new Service[0];//多个

StandardServer

 分析到这里,可知当前类代表了Server组件,那么tomcat启动的时候做了哪些初始化工作?,先不去分析复杂代码,以及继承类,看主要工作(功能):

启动时调用流程:initInternal()startInternal()

  • addService() 添加子组件,把子组件(web服务)添加到 services 变量中
  • initInternal(),代码如下,忽略其他,可以看到主要是循环调用service的init,这个也可以在上面流程图中有体现
@Override
    protected void initInternal() throws LifecycleException {
        super.initInternal();
//...忽略的代码
// Initialize our defined Services
for (Service service : services) {
    service.init();
}
}
  • startInternal()
protected void startInternal() throws LifecycleException {
    	fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);
globalNamingResources.start();
// Start our defined Services
synchronized (servicesLock) {
    for (Service service : services) {
        service.start();
    }
}
}

可以看出主要其调用了 service组件的start()方法

  • destroyInternal() 销毁每个 service
  • await() 这个很重要,主要是监听8005,如果返回,也就是下面代码中接收到 SHOTDOWN后break,tomcat会停止

public void await() {
    ...

    // Set up a server socket to wait on
    try {
    awaitSocket = new ServerSocket(getPortWithOffset(), 1,
                                   InetAddress.getByName(address));//创建 socket 监听:8005 
} catch (IOException e) {
    log.error(sm.getString("standardServer.awaitSocket.fail", address,
                           String.valueOf(getPortWithOffset()), String.valueOf(getPort()),
                           String.valueOf(getPortOffset())), e);
    return;
}

try {
    awaitThread = Thread.currentThread();

    // Loop waiting for a connection and a valid command
    while (!stopAwait) {
        ServerSocket serverSocket = awaitSocket;
        if (serverSocket == null) {
            break;
        }

        // Wait for the next connection
        Socket socket = null;
        StringBuilder command = new StringBuilder();
        try {
            InputStream stream;
            long acceptStartTime = System.currentTimeMillis();
            try {
                socket = serverSocket.accept();//阻塞
                socket.setSoTimeout(10 * 1000);  // Ten seconds
                stream = socket.getInputStream();
            } catch (SocketTimeoutException ste) {
                continue;
            } catch (AccessControlException ace) {
                continue;
            } catch (IOException e) {
                if (stopAwait) {
                    break;
                }
                break;
            }

            // Read a set of characters from the socket
            //这一堆代码就是解析 上边 stream 接受到的内容,放到 变量 command 中

                // Match against our command string
                boolean match = command.toString().equals(shutdown); //就是 SHUTDOWN
            
                if (match) 
                //如果是停止服务命令"" 就退出服务
                log.info(sm.getString("standardServer.shutdownViaPort"));
                break;
            } else {
                log.warn(sm.getString("standardServer.invalidShutdownCommand", command.toString()));
            }
            }
            }

利用8005端口关闭tomcat

使用telnet命令关闭,可百度window如何开启和使用,所以8005是绝不能外网开放的

//cmd 
telnet localhost 8005
此时会链接成功 弹出新窗口,直接输入 SHUTDOWN

如下8005端口接受到SHUTDOWN命令,跳出阻塞,往下执行,后续就是停止tomcat的方法

总结

Server组件是在初始化的时候被Catalina load方法调用,后续开启的组件调用链。当前类主要是socket监听8005端口,一旦接受到SHUTDOWN 就会停止tomcat的运行,所以8005不要对外网开放。


http://lihuaxi.xjx100.cn/news/559489.html

相关文章

<C++>二叉树进阶

文章目录为什么要学这一节1. 二叉搜索树1.1 二叉搜索树概念1.2 二叉搜索树操作1.3 二叉搜索树的实现1.4 二叉搜索树的应用1.5 二叉搜索树的性能分析2. 经典题目2.1 最近公共祖先2.2 从前序与中序遍历序列构造二叉树2.3 二叉树的前序遍历(非递归)为什么要…

vue新春游戏-拼手速抢车票小游戏,学习玩乐两不误,春节小游戏,新年小游戏

ue新春游戏-拼手速抢车票,老规矩,体验地址:http://game.pkec.net/word-ticket/。 写这个主要是前几天群里运营老师说咋没人写抢车票的,再加上我上一篇文章上了掘金一周,听说多上几次有证书,我还没搞到过掘金…

JVM垃圾回收相关算法-垃圾清除阶段

文章目录学习资料垃圾回收相关算法垃圾清除阶段标记-清除(Mark - Sweep)算法复制算法标记-压缩(或标记-整理、Mark - Compact)算法分代收集算法增量收集算法分区算法学习资料 【尚硅谷宋红康JVM全套教程(详解java虚拟…

FORM中的日历开发

Calendar是Template提供给我们的standard object.可以使我们方便的为日期型字段提供日期的选择列表. 为项指定值列表 KEY-LISTVAL触发器 calendar.show; calendar.show(SYSDATE);--显示当前时间 相关函数 calendar.show(first_date date default null) calendar.setup(new…

Airtest的UI自动化二、项目初始化

Airtest的UI自动化二、项目初始化 gitlab新建项目 公司的gitlab创建完项目之后还必须添加一个readme.md文档才会真正的创建master分支哦 然后下载到本地 添加虚拟环境 安装基础依赖 pip3 install airtest //airtest引入pip3 install allure-pytest //生成自己想要格式的…

XMLHttpRequest的基本使用

1、什么XMLHttpRequest XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,通过它,可以请求服务器上的数据资源。之前所学的 jQuery 中的 Ajax 函数,就是基于 xhr 对象封装出来的。 2、使用xhr发起GET请求 步骤…

Prometheus配合 alertmanager 使用邮箱报警

部署Prometheus 和 Alertmanager略 安装包部署prometheusGrafananode_exporter_争取不加班!的博客-CSDN博客 prometheus监控报警部署Alertmanager_争取不加班!的博客-CSDN博客 编辑Alertmanager配置文件 vim alertmanager/alertmanager.yml global: res…

InheritableThreadLocal原理、意义及其用法

InheritableThreadLocal可以做什么? 首先,InheritableThreadLocal也是一种ThreadLocal, 可以用于存放变量, 这个变量用于当前线程共享, 不同线程之间隔离. 有人可能会说,InheritableThreadLocal可以使得多个子线程共享父线程的变量。其实这…