Tomcat的server启动

article/2025/11/10 1:16:32

1.server的启动

前面我们说过了,server的启动过程主要是通过catalina进行一个启动,而在启动过程中他又经历了哪些过程呢?

从代码中看,server的启动过程中,他继承了lifecycleMbeanBase这个类并且实现了接口server,

而在这lifecycleMbeanBase类中又继承了LifecycleBase这个类,并且LifecycleBase复写了他父接口其中的initInternal和startInter这两个方法,这两个方法是一个模板方法。

server的启动过程中还有一个重要的方法叫做await方法,就是catalina就是调用他进入到了等待状态,进入到了等待状态,其中


        // Negative values - don't wait on port - tomcat is embedded or we just don't like ports
        if( port == -2 ) {
            // undocumented yet - for embedding apps that are around, alive.
            return;
        }
        if( port==-1 ) {
            try {
                awaitThread = Thread.currentThread();
                while(!stopAwait) {
                    try {
                        Thread.sleep( 10000 );
                    } catch( InterruptedException ex ) {
                        // continue and check the flag
                    }
                }
            } finally {
                awaitThread = null;
            }
            return;
        }

        // Set up a server socket to wait on
        try {
            awaitSocket = new ServerSocket(port, 1,
                    InetAddress.getByName(address));
        } catch (IOException e) {
            log.error("StandardServer.await: create[" + address
                               + ":" + port
                               + "]: ", 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) {
                        // This should never happen but bug 56684 suggests that
                        // it does.
                        log.warn(sm.getString("standardServer.accept.timeout",
                                Long.valueOf(System.currentTimeMillis() - acceptStartTime)), ste);
                        continue;
                    } catch (AccessControlException ace) {
                        log.warn("StandardServer.accept security exception: "
                                + ace.getMessage(), ace);
                        continue;
                    } catch (IOException e) {
                        if (stopAwait) {
                            // Wait was aborted with socket.close()
                            break;
                        }
                        log.error("StandardServer.await: accept: ", e);
                        break;
                    }

                    // Read a set of characters from the socket
                    int expected = 1024; // Cut off to avoid DoS attack
                    while (expected < shutdown.length()) {
                        if (random == null)
                            random = new Random();
                        expected += (random.nextInt() % 1024);
                    }
                    while (expected > 0) {
                        int ch = -1;
                        try {
                            ch = stream.read();
                        } catch (IOException e) {
                            log.warn("StandardServer.await: read: ", e);
                            ch = -1;
                        }
                        // Control character or EOF (-1) terminates loop
                        if (ch < 32 || ch == 127) {
                            break;
                        }
                        command.append((char) ch);
                        expected--;
                    }
                } finally {
                    // Close the socket now that we are done with it
                    try {
                        if (socket != null) {
                            socket.close();
                        }
                    } catch (IOException e) {
                        // Ignore
                    }
                }

                // Match against our command string
                boolean match = command.toString().equals(shutdown);
                if (match) {
                    log.info(sm.getString("standardServer.shutdownViaPort"));
                    break;
                } else
                    log.warn("StandardServer.await: Invalid command '"
                            + command.toString() + "' received");
            }
        } finally {
            ServerSocket serverSocket = awaitSocket;
            awaitThread = null;
            awaitSocket = null;

            // Close the server socket and return
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    // Ignore
                }
            }
        }
    这个方法中写着,当Tomcat的端口为-2时则直接退出等待状态,关闭Tomcat,如果为-1时则会一直循环,当stopAwait为图二时才会停止,而当为其他端口时,也会进入一个循环,这个循环可以跳出,有break,当指定的端口监听到shutdown一样的命令时,Tomcat就会关闭。

2.service的启动过程。

service也实现了LifecycleMBeanBase这个方法,从里面

protected void startInternal() throws LifecycleException {

        if(log.isInfoEnabled())
            log.info(sm.getString("standardService.start.name", this.name));
        setState(LifecycleState.STARTING);

        // Start our defined Container first
        if (container != null) {
            synchronized (container) {
                container.start();
            }
        }

        synchronized (executors) {
            for (Executor executor: executors) {
                executor.start();
            }
        }

        // Start our defined Connectors second
        synchronized (connectorsLock) {
            for (Connector connector: connectors) {
                try {
                    // If it has already failed, don't try and start it
                    if (connector.getState() != LifecycleState.FAILED) {
                        connector.start();
                    }
                } catch (Exception e) {
                    log.error(sm.getString(
                            "standardService.connector.startFailed",
                            connector), e);
                }
            }
        }
    }

    protected void startInternal() throws LifecycleException {

        if(log.isInfoEnabled())
            log.info(sm.getString("standardService.start.name", this.name));
        setState(LifecycleState.STARTING);

        // Start our defined Container first
        if (container != null) {
            synchronized (container) {
                container.start();
            }
        }

        synchronized (executors) {
            for (Executor executor: executors) {
                executor.start();
            }
        }

        // Start our defined Connectors second
        synchronized (connectorsLock) {
            for (Connector connector: connectors) {
                try {
                    // If it has already failed, don't try and start it
                    if (connector.getState() != LifecycleState.FAILED) {
                        connector.start();
                    }
                } catch (Exception e) {
                    log.error(sm.getString(
                            "standardService.connector.startFailed",
                            connector), e);
                }
            }
        }
    }

从他的初始化方法和start方法中可以看出来,他调用用了container,executors,connector等组件。其中container也就是我们说的container容器,executors是是executor的线程池, 

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->
这个线程池最多能够启用150个,最少四个线程。这样整个Tomcat就启动了。下面这个图片是转载的。大概就是这么个过程、

è¿éåå¾çæè¿°


http://chatgpt.dhexx.cn/article/L47IeHqx.shtml

相关文章

tomcat(17)启动tomcat

【0】README 1&#xff09;本文部分文字描述转自“how tomcat works”&#xff0c;旨在学习“tomcat(17)启动tomcat”的相关知识&#xff1b; 2&#xff09;本文重点关注启动Tomcat时会用到的两个类&#xff0c;分别是Catalina类和 Bootstrap类&#xff1b;&#xff08;干货——…

Tomcat的安装和启动

前言&#xff1a;Tomcat 是 Servlet 容器的一种&#xff0c;它是一个小型的&#xff08;体积小&#xff09;、轻量级的、免费开源的 Java Web 服务器。Tomcat 运行时占用的系统资源少&#xff0c;性能稳定&#xff0c;并且采用了先进和前沿的技术&#xff0c;所以它成为目前比较…

Tomcat安装及启动

日升时奋斗&#xff0c;日落时自省 目录 1、Tomcat下载 2、JDK安装及配置环境 3、Tomcat配置环境 4、启动Tomcat 5、部署演示 1、Tomcat下载 直接入主题&#xff0c;下载Tomcat 首先就是别下错了&#xff0c;直接找官方如何看是不是广告&#xff0c;或者造假 搜索Tomc…

Tomcat启动流程

一、流程简述 在Tomcat的bin目录下存放着Tomcat在Windows环境下和Linux环境下的启动脚本 在start脚本文件中会去启动catalina的脚本文件 catalina脚本文件中会去调用启动类(org.apache.catalina.startup.Bootstrap)来进行Tomcat的初始化 启动的流程图如下 二、启动流程 Init …

两种启动tomcat的方法

一&#xff0c;找到 Tomcat 目录下的 bin 目录下的 startup.bat 文件&#xff0c;双击&#xff0c;就可以启动 Tomcat 服务器 在D:\Tomcat\apache-tomcat-8.0.50\bin下找到setclasspath.bat右击编辑&#xff0c;在最后输入pause&#xff0c;即可查看错误 二&#xff0c;1打开命…

idea热启动

快捷键&#xff1a;ctrlshiftalt/ 然后重启 IDEA 注意&#xff1a;开发阶段开启热部署&#xff0c;生产阶段必须关闭

IntelliJ2021 设置热启动

在IntelliJ中设置了热启动后&#xff0c;更改代码保存后&#xff0c;系统会自动重启&#xff0c;无需手动重启。 1. IntelliJ2021 设置热启动 File -> settings -> Advanced Settings ,选中下面的选项 在pom.xml中 <dependency><groupId>org.springfram…

springboot 配置热启动

为解决开发过程中功能调试过程中的频繁启动项目的烦恼&#xff0c;可以为项目添加热启动&#xff0c;使得修改项目逻辑后&#xff0c;无需重启项目&#xff0c;即可实时使新修改的代码生效。 1、添加如下配置即可 <dependency><groupId>org.springframework.boot&…

SpringBoot 项目实现热启动

引入依赖。在pom.xml 文件 <dependencies></ dependencies> 添加如下内容 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> </de…

eclipse实现热部署和热启动

eclipse实现热部署和热启动 &#xff08;1&#xff09; 热部署:就是容器状态在运行的情况下重新部署整个项目.在这种情况下一般整个内存会清空,重新加载.简单来说就是Tomcat或者其他的web服务器会帮我们重新加载项目.这种方式可能会造成sessin丢失等情况. &#xff08;2&#x…

MIKE水动力笔记8_冷启动与热启动

本文目录 前言Step 1 冷启动与热启动的概念Step 2 案例的简介与对比设置Step 3 热启动初始条件文件的获取Step 4 冷启动与热启动的运行结果对比 前言 在本系列博文【MIKE水动力笔记5_建立水动力模型】中&#xff0c;在讲【Step 2 设置模型参数】中的【Initial Conditions】时&…

springboot热启动与热部署

一、热启动&#xff1a; 每自修改后&#xff0c; 程序自动启动spring Application上下文。 Pom中直接添加依赖即可&#xff1a; [html] view plain copy <dependency> <groupId>org.springframework.boot</groupId> <artif…

idea怎么设置热启动

idea更改代码后每次都需要重新启动才生效&#xff0c;如果需要进行多次小幅度调整时就会显得很繁琐&#xff0c;下面介绍一种更改代码后自动生效的热启动小技巧 以IntelliJ IDEA 2021.2.3汉化版为例进行设置热启动 1、运行》编辑配置。 2、执行“更新”操作时和切换出IDE时选…

【SpringBoot】springboot启动热部署

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ SpringBoot——手工启动热部署 一、pom.xml导入…

Java(四):高效调试之IDEA热启动

项目背景&#xff1a; 在开发过程&#xff0c;遇到问题要进行调试的时候&#xff0c;每次修改完代码&#xff0c;都需要重启应用&#xff0c;重新运行才能看到效果。配置了热启动后&#xff0c;修改代码后就不需要重启程序也可以看到效果&#xff0c;从而大大提升了开发效率。 …

键盘上什么组合键表示热启动计算机,什么是电脑热启动?电脑怎么热启动

什么是电脑热启动? 电脑热启动又称键盘启动&#xff0c;在不断电状态下(即开机状态下)进行的电脑程序启动&#xff0c;就叫做电脑热启&#xff0c;也可以简化为热启动。 电脑怎么热启动? 电脑在DOS状态下运行时&#xff0c;即同时按下键盘上的CtrlAltDelete组合键&#xff0c…

IDEA如何设置热启动

背景 在开发过程中&#xff0c;当写完一个功能我们需要运行应用程序测试&#xff0c;可能这个小功能中存在多个小bug&#xff0c;我们需要改正后重启服务器&#xff0c;这无形之中拖慢了开发的速度增加了开发时间&#xff0c;SpringBoot提供了spring-boot-devtools&#xff0c…

数据预处理的步骤

数据清理–>数据集成 —>数据归约–>数据变换 1.数据清理 就是处理脏数据&#xff0c;包括填写缺失值、清除噪声数据&#xff08;降噪&#xff09;、纠正不一致数据、识别或删除离群点等。常用工具例如&#xff1a;ETL工具 2.数据集成&#xff08;data integration)…

数据预处理-python实现

首先是数据读取&#xff1a;格式主要有excel,csv,txt等 import pandas as pd data pd.read_csv(r../filename.csv) #读取csv文件 data pd.read_table(r../filename.txt) #读取txt文件 data pd.read_excel(r../filename.xlsx) #读取excel文件# 获取数据库中的数据 import …

机器学习与数据挖掘——数据预处理

如果有兴趣了解更多相关内容&#xff0c;欢迎来我的个人网站看看&#xff1a;瞳孔空间 一&#xff1a;关于数据预处理 在工程实践中&#xff0c;我们得到的数据会存在有缺失值、重复值等&#xff0c;在使用之前需要进行数据预处理。数据预处理没有标准的流程&#xff0c;通常…